Uralter Thread, aber es gibt neue Möglichkeiten, ein Äquivalent auszuführen isset()
.
ESNext (Phase 4 Dezember 2019)
Zwei neue Syntax ermöglichen es uns, die Verwendung von isset()
Funktionen erheblich zu vereinfachen :
Bitte lesen Sie die Dokumente und beachten Sie die Browserkompatibilität.
Vorherige Antwort
Siehe unten für eine Erklärung. Hinweis Ich verwende die StandardJS-Syntax
Beispiel Verwendung
// 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
Antwortfunktion
/**
* 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
}
}
Erläuterung
PHP
Beachten Sie, dass Sie in PHP auf jede Variable in jeder Tiefe verweisen können. Selbst wenn Sie versuchen, auf ein Nicht-Array als Array zuzugreifen, wird ein einfaches true
oder Folgendes zurückgegeben 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
In JavaScript haben wir diese Freiheit nicht. Wenn wir dasselbe tun, wird immer eine Fehlermeldung angezeigt, da JS sofort versucht, auf den Wert von zuzugreifen, deeper
bevor wir ihn in unsere isset()
Funktion einbinden können.
// 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
Weitere fehlgeschlagene Alternativen:
// 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
Und einige funktionierende Alternativen, die schnell überflüssig werden können:
// 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
Fazit
Alle anderen Antworten - obwohl die meisten realisierbar sind ...
- Angenommen, Sie überprüfen nur, ob die Variable nicht undefiniert ist, was für einige Anwendungsfälle in Ordnung ist, aber dennoch einen Fehler auslösen kann
- Angenommen, Sie versuchen nur, auf eine Eigenschaft der obersten Ebene zuzugreifen, was für einige Anwendungsfälle wiederum in Ordnung ist
- Erzwingen Sie einen weniger idealen Ansatz in Bezug auf PHPs,
isset()
zisset(some, 'nested.deeper.value')
- Verwenden Sie,
eval()
was funktioniert, aber ich persönlich vermeide
Ich glaube, ich habe viel davon behandelt. In meiner Antwort mache ich einige Punkte, die ich nicht anspreche, weil sie - obwohl relevant - nicht Teil der Frage sind. Bei Bedarf kann ich meine Antwort jedoch mit Links zu einigen der technischeren Aspekte aktualisieren, je nach Bedarf.
Ich habe viel Zeit damit verbracht, hoffentlich hilft es den Leuten dabei.
Danke fürs Lesen!