Ein altes Thema, aber es gibt neue Wege, ein Äquivalent zu betreiben isset()
.
ESNext (Stufe 4 Dezember 2019)
Zwei neue Syntaxen ermöglichen es uns, die Verwendung von isset()
Funktionalität:
Bitte lesen Sie die Dokumente und achten Sie auf die Browserkompatibilität.
Antwort
Siehe unten für eine Erklärung. Hinweis: Ich verwende die StandardJS-Syntax
Beispiel für die 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
Antwort Funktion
/**
* Checks to see if a value is set.
*
* @param {Function} accessor Function that returns our value
* @returns {Boolean} Value is not undefined or null
*/
function isset (accessor) {
try {
// Note we're seeing if the returned value of our function is not
// undefined or null
return accessor() !== undefined && accessor() !== null
} catch (e) {
// And we're able to catch the Error it would normally throw for
// referencing a property of undefined
return false
}
}
NPM-Paket
Diese Antwortfunktion ist verfügbar als isset-php
Paket auf NPM. Das Paket enthält einige Verbesserungen wie Typüberprüfung und Unterstützung mehrerer Argumente.
npm install --save isset-php
Die vollständige Dokumentation finden Sie in der README .
const isset = require('isset-php')
let val = ''
// This will evaluate to true so the text will be printed.
if (isset(() => val)) {
console.log('This val is set so I will print.')
}
Erläuterung
PHP
Beachten Sie, dass Sie in PHP auf jede Variable in jeder Tiefe verweisen können - selbst der Versuch, auf ein auf ein Nicht-Array als Array zuzugreifen, gibt eine einfache 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
JavaScript
In JavaScript haben wir diese Freiheit nicht; wir werden immer einen Fehler erhalten, wenn wir dasselbe tun dasselbe tun, weil die Engine sofort versucht, auf den Wert von deeper
bevor wir es in unser isset()
Funktion so...
// 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
Mehr fehlende Alternativen:
// Any way we attempt to access the `deeper` property of `nested` will
// throw an error
some.nested.deeper.hasOwnProperty('value') // Error
// ^^^^^^ undefined
// Similar to the above but safe from objects overriding `hasOwnProperty`
Object.prototype.hasOwnProperty.call(some.nested.deeper, 'value') // 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 {
if (isset(some.nested.deeper)) {
// ...
}
} catch (e) {}
try {
if (some.nested.deeper !== undefined && some.nested.deeper !== null) {
// ...
}
} 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
Schlussfolgerung
Alle anderen Antworten - obwohl die meisten machbar sind...
- Gehen Sie davon aus, dass Sie nur prüfen wollen, ob die Variable nicht undefiniert ist. für einige Anwendungsfälle in Ordnung ist, aber trotzdem einen Fehler auslösen kann
- Nehmen Sie an, dass Sie nur versuchen, auf eine Eigenschaft der obersten Ebene zuzugreifen, was wiederum für einige für einige Anwendungsfälle in Ordnung
- Sie dazu zwingen, einen weniger idealen Ansatz als den von PHP zu verwenden
isset()
z.B.. isset(some, 'nested.deeper.value')
- 使用方法
eval()
was funktioniert, aber ich persönlich vermeide
Ich denke, ich habe eine Menge davon abgedeckt. Es gibt einige Punkte in meiner Antwort, die ich nicht anspreche, weil sie - obwohl relevant - nicht Teil der Frage sind Frage sind (z.B.. Kurzschluss ). Falls erforderlich, kann ich meine Antwort jedoch mit Links zu einigen der technischen Aspekten auf Anfrage aktualisieren.
Ich habe viel zu viel Zeit damit verbracht, also hoffe ich, dass es den Leuten weiterhilft.
Vielen Dank fürs Lesen!