Discussione antica, ma ci sono nuovi modi per eseguire un equivalente isset()
.
ESSuccessivo (tappa 4 dicembre 2019)
Due nuove sintassi ci consentono di semplificare notevolmente l'uso della isset()
funzionalità:
Si prega di leggere i documenti e tenere presente la compatibilità del browser.
Risposta precedente
Vedi sotto per la spiegazione. Nota Uso la sintassi StandardJS
Esempio di utilizzo
// 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
Funzione di risposta
/**
* 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
}
}
Spiegazione
PHP
Si noti che in PHP è possibile fare riferimento a qualsiasi variabile a qualsiasi profondità, anche provando ad accedere a un non-array poiché un array restituirà un semplice true
o 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, non abbiamo quella libertà, avremo sempre un errore se facciamo lo stesso perché JS tenta immediatamente di accedere al valore deeper
prima di poterlo avvolgere nella nostra isset()
funzione, quindi ...
// 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
Altre alternative inadempienti:
// 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
E alcune alternative funzionanti che possono essere ridondanti velocemente:
// 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
Conclusione
Tutte le altre risposte, sebbene la maggior parte sia praticabile ...
- Supponiamo che stai solo verificando se la variabile non è indefinita, il che va bene per alcuni casi d'uso ma può comunque generare un errore
- Supponiamo che stai solo tentando di accedere a una proprietà di livello superiore, che di nuovo va bene per alcuni casi d'uso
- Ti costringono a usare un approccio meno che ideale rispetto ai PHP,
isset()
ad esisset(some, 'nested.deeper.value')
- Usa
eval()
quale funziona ma evito personalmente
Penso di averne coperto molto. Ci sono alcuni punti che sottolineo nella mia risposta di cui non tengo conto perché, sebbene pertinenti, non fanno parte della domanda. Se necessario, tuttavia, posso aggiornare la mia risposta con collegamenti ad alcuni degli aspetti più tecnici basati sulla domanda.
Ho passato molto tempo con questo, quindi spero che aiuti le persone.
Grazie per aver letto!