Un thread ancien, mais il existe de nouvelles façons d'exécuter un équivalent isset()
.
ESNext (étape 4 décembre 2019)
Deux nouvelles syntaxes nous permettent de simplifier considérablement l'utilisation des isset()
fonctionnalités:
Veuillez lire la documentation et faire attention à la compatibilité du navigateur.
Réponse précédente
Voir ci-dessous pour l'explication. Remarque J'utilise la syntaxe StandardJS
Exemple d'utilisation
// IMPORTANT pass a function to our isset() that returns the value we're
// trying to test(ES6 arrow function)
isset(() => some) // false
// Defining objects
let some = { nested: { value: 'hello' } }
// More tests that never throw an error
isset(() => some) // true
isset(() => some.nested) // true
isset(() => some.nested.value) // true
isset(() => some.nested.deeper.value) // false
// Less compact but still viable except when trying to use `this` context
isset(function () { return some.nested.deeper.value }) // false
Fonction de réponse
/**
* Checks to see if a value is set.
*
* @param {Function} accessor Function that returns our value
*/
function isset (accessor) {
try {
// Note we're seeing if the returned value of our function is not
// undefined
return typeof accessor() !== 'undefined'
} catch (e) {
// And we're able to catch the Error it would normally throw for
// referencing a property of undefined
return false
}
}
Explication
PHP
Notez qu'en PHP, vous pouvez référencer n'importe quelle variable à n'importe quelle profondeur - même essayer d'accéder à un non-tableau en tant que tableau retournera un simple true
ou false
:
// Referencing an undeclared variable
isset($some); // false
$some = 'hello';
// Declared but has no depth(not an array)
isset($some); // true
isset($some['nested']); // false
$some = ['nested' => 'hello'];
// Declared as an array but not with the depth we're testing for
isset($some['nested']); // true
isset($some['nested']['deeper']); // false
JS
En JavaScript, nous n'avons pas cette liberté, nous aurons toujours une erreur si nous faisons de même car JS essaie immédiatement d'accéder à la valeur de deeper
avant de pouvoir l'envelopper dans notre isset()
fonction donc ...
// Common pitfall answer(ES6 arrow function)
const isset = (ref) => typeof ref !== 'undefined'
// Same as above
function isset (ref) { return typeof ref !== 'undefined' }
// Referencing an undeclared variable will throw an error, so no luck here
isset(some) // Error: some is not defined
// Defining a simple object with no properties - so we aren't defining
// the property `nested`
let some = {}
// Simple checking if we have a declared variable
isset(some) // true
// Now trying to see if we have a top level property, still valid
isset(some.nested) // false
// But here is where things fall apart: trying to access a deep property
// of a complex object; it will throw an error
isset(some.nested.deeper) // Error: Cannot read property 'deeper' of undefined
// ^^^^^^ undefined
Plus d'alternatives défaillantes:
// Any way we attempt to access the `deeper` property of `nested` will
// throw an error
some.nested.deeper.hasOwnProperty('value') // Error
// ^^^^^^ undefined
Object.hasOwnProperty('value', some.nested.deeper) // Error
// ^^^^^^ undefined
// Same goes for typeof
typeof some.nested.deeper !== 'undefined' // Error
// ^^^^^^ undefined
Et quelques alternatives de travail qui peuvent devenir redondantes rapidement:
// Wrap everything in try...catch
try { isset(some.nested.deeper) } catch (e) {}
try { typeof some.nested.deeper !== 'undefined' } catch (e) {}
// Or by chaining all of the isset which can get long
isset(some) && isset(some.nested) && isset(some.nested.deeper) // false
// ^^^^^^ returns false so the next isset() is never run
Conclusion
Toutes les autres réponses - bien que la plupart soient viables ...
- Supposons que vous vérifiez uniquement si la variable n'est pas indéfinie, ce qui convient à certains cas d'utilisation, mais peut toujours générer une erreur
- Supposons que vous essayez uniquement d'accéder à une propriété de niveau supérieur, ce qui est encore bien pour certains cas d'utilisation
- Vous forcer à utiliser une approche moins qu'idéal par rapport à PHP,
isset()
par exempleisset(some, 'nested.deeper.value')
- Utilisez
eval()
ce qui fonctionne mais j'évite personnellement
Je pense que j'en ai couvert beaucoup. Il y a certains points que je soulève dans ma réponse que je n'aborde pas car ils - bien que pertinents - ne font pas partie de la question. Si besoin est, cependant, je peux mettre à jour ma réponse avec des liens vers certains des aspects les plus techniques en fonction de la demande.
J'ai passé trop de temps sur ce sujet, donc j'espère que cela aide les gens.
Merci pour la lecture!