JavaScript isset () equivalente


553

In PHP puoi farlo if(isset($array['foo'])) { ... }. In JavaScript si usa spesso if(array.foo) { ... }per fare lo stesso, ma questa non è esattamente la stessa affermazione. La condizione valuterà anche su false se array.fooesiste ma è falseo 0(e probabilmente anche altri valori).

Qual è l'equivalente perfetto di PHP issetin JavaScript?

In senso lato, sarebbe utile una guida generale e completa sulla gestione di variabili inesistenti da parte di JavaScript, variabili senza valore, ecc.


1
Ho scritto una funzione che verificherà l'esistenza di una proprietà di oggetti indipendentemente dalla profondità della query: stackoverflow.com/a/12681101/1268003 Usando il mio codice, combinato con alcune conoscenze condivise da @CMS in questo thread, puoi facilmente scrivere un globale funzione che funziona in modo molto simile a isset di PHP: s.
Martin Andersson,

3
Se usi Underscore.js prova_.isUndefined(arr.foo)
Vitalii Fedorenko

Opzionale concatenamento è probabilmente quello che molte persone saranno in cerca di stackoverflow.com/a/60845999/2100372
zoran404

Risposte:


938

In genere utilizzo l' typeofoperatore:

if (typeof obj.foo !== 'undefined') {
  // your code here
}

Restituirà "undefined"o se la proprietà non esiste o il suo valore è undefined.

(Vedi anche: Differenza tra undefinede non essere definita. )

Esistono altri modi per capire se esiste una proprietà su un oggetto, come il hasOwnPropertymetodo:

if (obj.hasOwnProperty('foo')) {
  // your code here
}

E l' inoperatore:

if ('foo' in obj) {
  // your code here
}

La differenza tra gli ultimi due è che il hasOwnPropertymetodo verificherà se la proprietà esiste fisicamente sull'oggetto (la proprietà non è ereditata).

L' inoperatore verificherà tutte le proprietà raggiungibili nella catena di prototipi, ad esempio:

var obj = { foo: 'bar'};

obj.hasOwnProperty('foo'); // true
obj.hasOwnProperty('toString'); // false
'toString' in obj; // true

Come puoi vedere, hasOwnPropertyritorna falsee l' inoperatore ritorna truequando controlla il toStringmetodo, questo metodo è definito nella catena del prototipo, perché objeredita la forma Object.prototype.


23
Perché usare typeofpiuttosto che if( obj.foo !== undefined )?
Matt Ball,

7
Ah. Un giorno scriverò un pezzo di Javascript veramente cross-browser. Fino ad allora ...
Matt Ball,

37
il problema è che si verifica un errore quando si tenta di controllare proprietà più profonde, ad esempio: obj.thisdoesntexist.foo! == undefined. In PHP puoi usare isset o empty e in sicurezza a qualsiasi profondità.
Enrique,

6
IE8 non ha "hasOwnPropery"
max4ever il

12
Esattamente, PHP consente isset($abc->def->ghi->jkl)senza sollevare un'eccezione e arrestare lo script, a differenza typeofdell'operatore JavaScript . Devi usare qualcosa del genere try{ abc.def.ghi.jkl; isset=true } catch(e){ isset=false }
Steven Pribilinskiy,

43

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 trueo 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 ...

  1. 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
  2. Supponiamo che stai solo tentando di accedere a una proprietà di livello superiore, che di nuovo va bene per alcuni casi d'uso
  3. Ti costringono a usare un approccio meno che ideale rispetto ai PHP, isset()
    ad esisset(some, 'nested.deeper.value')
  4. 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!


25

Riferimento a SOURCE

    module.exports = function isset () {
  //  discuss at: http://locutus.io/php/isset/
  // original by: Kevin van Zonneveld (http://kvz.io)
  // improved by: FremyCompany
  // improved by: Onno Marsman (https://twitter.com/onnomarsman)
  // improved by: Rafał Kukawski (http://blog.kukawski.pl)
  //   example 1: isset( undefined, true)
  //   returns 1: false
  //   example 2: isset( 'Kevin van Zonneveld' )
  //   returns 2: true

  var a = arguments
  var l = a.length
  var i = 0
  var undef

  if (l === 0) {
    throw new Error('Empty isset')
  }

  while (i !== l) {
    if (a[i] === undef || a[i] === null) {
      return false
    }
    i++
  }

  return true
}

phpjs.org è in gran parte ritirato a favore di locutus Ecco il nuovo link http://locutus.io/php/var/isset


6
Ciò genererà un'eccezione quando si chiama isset(abc.def.ghi)nel caso in cui abc.defnon sia definito. Tuttavia, combinando questa soluzione con quella che accetta un nome di variabile in una forma di stringa, sarà identica alla versione di PHP.
Steven Pribilinskiy,


8
//
//  tring to reference non-existing variable throws ReferenceError 
//  before test function is even executed
//
//  example, if you do:
//    
//     if ( isset( someVar ) ) 
//        doStuff( someVar );
//   
//  you get a ReferenceError ( if there is no someVar... ) 
//  and isset fn doesn't get executed.
//
//  if you pass variable name as string, ex. isset( 'novar' );, 
//  this might work:
//
function isset ( strVariableName ) { 

    try { 
        eval( strVariableName );
    } catch( err ) { 
        if ( err instanceof ReferenceError ) 
           return false;
    }

    return true;

 } 
//
//

8

Questa semplice soluzione funziona, ma non per il controllo approfondito degli oggetti.

function isset(str) {
    return window[str] !== undefined;
}

6

Uso sempre questa funzione generica per prevenire errori su variabili primitive, nonché su array e oggetti.

isset = function(obj) {
  var i, max_i;
  if(obj === undefined) return false;
  for (i = 1, max_i = arguments.length; i < max_i; i++) {
    if (obj[arguments[i]] === undefined) {
        return false;
    }
    obj = obj[arguments[i]];
  }
  return true;
};

console.log(isset(obj));                   // returns false
var obj = 'huhu';
console.log(isset(obj));                   // returns true
obj = {hallo:{hoi:'hoi'}};
console.log(isset(obj, 'niet'));           // returns false
console.log(isset(obj, 'hallo'));          // returns true
console.log(isset(obj, 'hallo', 'hallo')); // returns false
console.log(isset(obj, 'hallo', 'hoi'));   // returns true

5

Se stai usando underscorejs lo uso sempre

if (!_.isUndefined(data) && !_.isNull(data)) {
     //your stuff
}

4

Questa è una soluzione piuttosto antiproiettile per testare se esiste una variabile:

var setOrNot = typeof variable !== typeof undefined ? true : false;

Sfortunatamente, non puoi semplicemente incapsularlo in una funzione.

Potresti pensare di fare qualcosa del genere:

function isset(variable) {
    return typeof variable !== typeof undefined ? true : false;
}

Tuttavia, questo produrrà un errore di riferimento se la variabile variablenon è stata definita, poiché non è possibile passare una variabile inesistente a una funzione:

Errore di riferimento non rilevato: foo non è definito

D'altra parte, consente di verificare se i parametri della funzione non sono definiti:

var a = '5';

var test = function(x, y) {
    console.log(isset(x));
    console.log(isset(y));
};

test(a);

// OUTPUT :
// ------------
// TRUE
// FALSE

Anche se nessun valore per yviene passato alla funzione test, la nostra issetfunzione funziona perfettamente in questo contesto, perché yè noto nella funzione testcome undefinedvalore.


Minor nit: `? true: false` è superfluo. Il risultato di !==è già un booleano.
ToolmakerSteve

4
(typeof SOMETHING) !== 'undefined'

È troppo lungo per scrivere quando viene utilizzato. Ma non possiamo impacchettare la typeofparola chiave in una funzione, perché verrà generato un errore prima che la funzione venga chiamata, in questo modo:

function isdef($var) {
    return (typeof $var) !== 'undefined';
}

isdef(SOMETHING); ///// thrown error: SOMETHING is not defined

Quindi ho trovato un modo:

function isdef($type) {
    return $type !== 'undefined';
}

isdef(typeof SOMETHING);

Può funzionare sia con singole variabili (variabili che non esistono affatto), sia con proprietà degli oggetti (proprietà inesistenti). E solo 7 più personaggi di PHP isset.


Questo funziona per me, lo ha usato per verificare l'esistenza di una risposta json particolare.
Giulio

3

Questa soluzione ha funzionato per me.

function isset(object){
    return (typeof object !=='undefined');
}

5
Invocare isset(var)con varunset:ReferenceError: var is not defined
Gui Imamura,

3
function isset(variable) {
    try {
        return typeof eval(variable) !== 'undefined';
    } catch (err) {
        return false;
    }
}

4
aggiungi anche una descrizione.
Shree Krishna

Come già menzionato in diverse risposte precedenti, ciò genererà un ReferenceError se chiamato con una variabile che non è mai stata dichiarata. Ad esempio isset(someVar), dove someVarnon è mai stato dichiarato. Comunque, dato che lo fai eval, probabilmente intendi passare una stringa . Mostra l'utilizzo. È l'uso previsto isset('someVar')? In tal caso, sembra simile a questa risposta precedente : che dire della tua risposta è nuova?
ToolmakerSteve


3

Per verificare se il blocco html esiste o no, sto usando questo codice:

if (typeof($('selector').html()) != 'undefined') {
    // $('selector') is existing
    // your code here
}

2

Fornire il percorso dell'oggetto come stringa, quindi è possibile suddividere questa stringa in un percorso e risolverla hasOwnPropertyin ogni passaggio sovrascrivendo l'oggetto stesso con ogni iterazione.

Se stai codificando in ambiente ES6, dai un'occhiata a questo Stackoverflow Ques .

var a;

a = {
    b: {
        c: 'e'
    }
};

function isset (obj, path) {
    var stone;

    path = path || '';

    if (path.indexOf('[') !== -1) {
        throw new Error('Unsupported object path notation.');
    }

    
    path = path.split('.');
    
    do {
        if (obj === undefined) {
            return false;
        }

        stone = path.shift();
        
        if (!obj.hasOwnProperty(stone)) {
            return false;
        }
        
        obj = obj[stone];
        
    } while (path.length);

    return true;
}

console.log(
    isset(a, 'b') == true,
    isset(a, 'b.c') == true,
    isset(a, 'b.c.d') == false,
    isset(a, 'b.c.d.e') == false,
    isset(a, 'b.c.d.e.f') == false
);


2

Uso una funzione che può controllare variabili e oggetti. molto comodo per lavorare con jQuery

    function _isset (variable) {
        if(typeof(variable) == "undefined" || variable == null)
            return false;
        else
            if(typeof(variable) == "object" && !variable.length) 
                return false;
            else
                return true;
    };

Come già menzionato in diverse risposte precedenti, questo genererà un ReferenceError se chiamato con una variabile che non è mai stata dichiarata.
ToolmakerSteve

1

È stato davvero un problema per me quando stavo accedendo a una proprietà più profonda di un oggetto, quindi ho creato una funzione che restituirà il valore della proprietà se esiste, altrimenti restituirà false. Puoi usarlo per risparmiare tempo,

//Object on which we want to test
var foo = {
    bar: {
        bik: {
            baz: 'Hello world'
        }
    }
};


/*
USE: To get value from the object using it properties supplied (Deeper),
    if found it will return the property value if not found then will return false

You can use this function in two ways
WAY - 1:
Passing an object as parameter 1 and array of the properties as parameter 2
EG: getValueFromObject(foo, ['bar', 'bik', 'baz']);
WAY - 2: (This will work only if, your object available in window object)
Passing an STRING as parameter 1(Just similarly how we retrieve value form object using it's properties - difference is only the quote)
EG: getValueFromObject('foo.bar.bik.baz');
*/
function getValueFromObject(object, properties) {
    if(typeof(object) == 'string') {            //Here we extract our object and it's properties from the string
        properties = object.split('.');
        object = window[properties[0]];
        if(typeof(object) == 'undefined') {
            return false;
        }
        properties.shift();
    }
    var property = properties[0];
    properties.shift();
    if(object != null && typeof(object[property]) != 'undefined') {
        if(typeof(object[property]) == 'object') {
            if(properties.length != 0) {
                return getValueFromObject(object[property], properties);    //Recursive call to the function
            } else {
                return object[property];
            }
        } else {
            return object[property];
        }
    } else {
        return false;
    }
}
console.log(getValueFromObject('fooo.bar.bik.baz'));        //false
console.log(getValueFromObject('foo.bar.bik.baz'));         //Hello world
console.log(getValueFromObject('foo'));                     //false
console.log(getValueFromObject('foo.bar.bik'));             //returns an object { baz: 'Hello World' }
console.log(getValueFromObject(foo, ['bar', 'bik']));       //returns an object { baz: 'Hello World' }
console.log(getValueFromObject(foo, ['bar', 'bik', 'baz']));//Hello world

1

Se vuoi controllare se esiste un elemento, usa semplicemente il seguente codice:

if (object) {
  //if isset, return true
} else {
  //else return false
}

Questo è un esempio:

function switchDiv() {
    if (document.querySelector("#divId")) {
        document.querySelector("#divId").remove();
    } else {
        var newDiv = document.createElement("div");
        newDiv.id = "divId";
        document.querySelector("body").appendChild(newDiv);
    }
}

document.querySelector("#btn").addEventListener("click", switchDiv);
#divId {
    background: red;
    height: 100px;
    width: 100px;
    position: relative;
    
}
<body>
  <button id="btn">Let's Diiiv!</button>
</body>


0
if (var) {
  // This is the most concise equivalent of Php's isset().
} 

0

Il manuale di PHP dice:

isset : determina se una variabile è impostata e non è NULL

E interfaccia qualcosa del genere:

bool isset ( mixed $var [, mixed $... ] )

Il parametro $varè la variabile da verificare. può avere un numero qualsiasi di parametri però.

isset () restituisce TRUEse var esiste e ha un valore diverso da NULL. FALSEaltrimenti.

Qualche esempio:

$foo = 'bar';
var_dump(isset($foo));        -> true

$baz = null;
var_dump(isset($baz));        -> false

var_dump(isset($undefined));  -> false

Per questo motivo, a quanto pare, non è possibile scrivere l'equivalente esatto della isset()funzione php . Ad esempio, quando chiamiamo così:

if (isset(some_var)) {

}

function issset() {
    // function definition
}

Trigger Javascript Uncaught ReferenceError: some_var is not defined at (file_name):line_number. La cosa importante e notevole di questo comportamento è che quando si tenta di passare variabili inesistenti a funzioni normali, viene generato un errore.

Ma in PHP isset()non ci sono in realtà funzioni regolari ma costrutti di linguaggio. Ciò significa che fanno parte del linguaggio PHP stesso, non giocano secondo le normali regole delle funzioni e possono quindi cavarsela senza innescare un errore per variabili inesistenti. Questo è importante quando si cerca di capire se esiste o meno una variabile. Ma in javscript, in primo luogo genera un errore, ad esempio la chiamata di funzione con variabili inesistenti.

Il mio punto è che non possiamo scriverlo come una funzione javscript equivalente ma possiamo fare qualcosa del genere

if (typeof some_var !== 'undefined') {
   // your code here
}

Se vuoi esattamente lo stesso effetto PHP controlla anche che varable non lo sia NULL

Per esempio

$baz = null;
var_dump(isset($baz));        -> false

Quindi, possiamo incorporarlo in javascript, quindi assomiglia a questo:

if (typeof some_var !== 'undefined' && some_var !== null) {
   // your code here
}

0

isset javascript

let test = {
  a: {
    b: [0, 1]
  }
};

console.log(test.isset('a.b'))   // true
console.log(test.isset('a.b.1')) // true
console.log(test.isset('a.b.5')) // false
console.log(test.isset('a.c'))   // false
console.log('abv'.isset('0'))    // true

0

Fai attenzione in ES6 , tutte le soluzioni precedenti non funzionano se vuoi controllare una dichiarazione di una variabile let e dichiararla, se non lo è

esempio

let myTest = 'text';

if(typeof myTest === "undefined") {
    var myTest = 'new text'; // can't be a let because let declare in a scope
}

vedrai un errore

Uncaught SyntaxError: l'identificatore 'myTest' è già stato dichiarato

La soluzione era di cambiarlo di un var

var myTest = 'text'; // I replace let by a var

if(typeof myTest === "undefined") {
    var myTest = 'new text';
}

un'altra soluzione se è possibile modificare un let con un var, è necessario rimuovere il var

let myTest = 'text';

if(typeof myTest === "undefined") {
    myTest = 'new text'; // I remove the var declaration
}

-1
    isset('user.permissions.saveProject', args);

    function isset(string, context) {
        try {
            var arr = string.split('.');
            var checkObj = context || window;

            for (var i in arr) {
                if (checkObj[arr[i]] === undefined) return false;
                checkObj = checkObj[arr[i]];
            }

            return true;
        } catch (e) {
            return false;
        }
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.