Equivalent JavaScript isset ()

553

En PHP, vous pouvez le faire if(isset($array['foo'])) { ... }. En JavaScript, vous utilisez souvent if(array.foo) { ... }pour faire la même chose, mais ce n'est pas exactement la même déclaration. La condition sera également évaluée à false si array.fooelle existe mais est falseou 0(et probablement d'autres valeurs également).

Quel est l'équivalent parfait de PHP isseten JavaScript?

Dans un sens plus large, un guide général et complet sur la gestion par JavaScript des variables qui n'existent pas, des variables sans valeur, etc. serait pratique.

Bart van Heukelom
la source
1
J'ai écrit une fonction qui testera l'existence d'une propriété d'objets, peu importe la profondeur de la requête: stackoverflow.com/a/12681101/1268003 En utilisant mon code, combiné avec certaines connaissances partagées par @CMS dans ce fil, vous pouvez facilement écrire un global fonction qui fonctionne beaucoup comme PHP: s isset.
Martin Andersson
3
Si vous utilisez Underscore.js essayez_.isUndefined(arr.foo)
Vitalii Fedorenko
Le chaînage en option est probablement ce que la plupart des gens recherchent stackoverflow.com/a/60845999/2100372
zoran404

Réponses:

938

J'utilise généralement l' typeofopérateur:

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

Il retournera "undefined"soit si la propriété n'existe pas ou si sa valeur est undefined.

(Voir aussi: Différence entre undefinedet non défini. )

Il existe d'autres façons de déterminer si une propriété existe sur un objet, comme la hasOwnPropertyméthode:

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

Et l' inopérateur:

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

La différence entre les deux derniers est que la hasOwnPropertyméthode vérifie si la propriété existe physiquement sur l'objet (la propriété n'est pas héritée).

L' inopérateur vérifiera toutes les propriétés accessibles dans la chaîne du prototype, par exemple:

var obj = { foo: 'bar'};

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

Comme vous pouvez le voir, hasOwnPropertyretourne falseet l' inopérateur retourne truelors de la vérification de la toStringméthode, cette méthode est définie dans la chaîne du prototype, car objhérite de la forme Object.prototype.

CMS
la source
23
Pourquoi utiliser typeofplutôt que if( obj.foo !== undefined )?
Matt Ball
7
Ah. Un jour, j'écrirai un morceau de Javascript vraiment cross-browser. Jusque-là ...
Matt Ball
37
le problème avec ceci est que vous obtenez une erreur lorsque vous essayez de vérifier les propriétés plus profondes, par exemple: obj.thisdoesntexist.foo! == undefined. En PHP, vous pouvez utiliser isset ou vide et en toute sécurité à n'importe quelle profondeur.
Enrique
6
IE8 n'a pas "hasOwnPropery"
max4ever
12
Exactement, PHP permet isset($abc->def->ghi->jkl)sans déclencher une exception et arrêter le script, contrairement à l' typeofopérateur JavaScript . Vous devez utiliser quelque chose comme try{ abc.def.ghi.jkl; isset=true } catch(e){ isset=false }
Steven Pribilinskiy
43

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

  1. 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
  2. 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
  3. Vous forcer à utiliser une approche moins qu'idéal par rapport à PHP, isset()
    par exempleisset(some, 'nested.deeper.value')
  4. 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!

Enom
la source
25

Référence à 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 est principalement à la retraite en faveur de locutus Voici le nouveau lien http://locutus.io/php/var/isset

Ijas Ameenudeen
la source
6
Cela déclenchera une exception lors de l'appel isset(abc.def.ghi)au cas où if abc.defn'est pas défini. Cependant en combinant cette solution avec celle qui accepte un nom de variable sous forme de chaîne, elle sera identique à la version PHP.
Steven Pribilinskiy
17
if (!('foo' in obj)) {
  // not set.
}
kennytm
la source
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;

 } 
//
//
remplacement public
la source
8

Cette solution simple fonctionne, mais pas pour une vérification approfondie des objets.

function isset(str) {
    return window[str] !== undefined;
}
Rodolfo Jorge Nemer Nogueira
la source
6

J'utilise toujours cette fonction générique pour éviter les erreurs sur les variables primitives ainsi que sur les tableaux et les objets.

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
Innovaat
la source
5

Si vous utilisez des traits de soulignement, j'utilise toujours

if (!_.isUndefined(data) && !_.isNull(data)) {
     //your stuff
}
Del
la source
4

Ceci est une solution assez à l'épreuve des balles pour tester si une variable existe:

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

Malheureusement, vous ne pouvez pas simplement l'encapsuler dans une fonction.

Vous pourriez penser à faire quelque chose comme ça:

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

Cependant, cela produira une erreur de référence si la variable variablen'a pas été définie, car vous ne pouvez pas transmettre une variable non existante à une fonction:

Uncaught ReferenceError: foo n'est pas défini

D'un autre côté, cela vous permet de tester si les paramètres de fonction ne sont pas définis:

var a = '5';

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

test(a);

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

Même si aucune valeur yn'est transmise à la fonction test, notre issetfonction fonctionne parfaitement dans ce contexte, car elle yest connue dans la fonction testcomme une undefinedvaleur.

John Slegers
la source
Nit mineur: `? true: false` est superflu. Le résultat de !==est déjà un booléen.
ToolmakerSteve
4
(typeof SOMETHING) !== 'undefined'

Il est trop long pour écrire lorsqu'il est utilisé. Mais nous ne pouvons pas empaqueter le typeofmot - clé dans une fonction, car une erreur sera levée avant l'appel de la fonction, comme ceci:

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

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

J'ai donc trouvé un moyen:

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

isdef(typeof SOMETHING);

Il peut fonctionner à la fois avec des variables individuelles (variables qui n'existent pas du tout) ou des propriétés d'objet (propriétés inexistantes). Et seulement 7 caractères de plus que PHP isset.

LI XiangChen
la source
Cela fonctionne pour moi, l'a utilisé pour vérifier si une réponse json particulière existait.
Julius
3

Cette solution a fonctionné pour moi.

function isset(object){
    return (typeof object !=='undefined');
}
Bastien Viatge
la source
5
Invocation isset(var)avec varunset:ReferenceError: var is not defined
Gui Imamura
3
function isset(variable) {
    try {
        return typeof eval(variable) !== 'undefined';
    } catch (err) {
        return false;
    }
}
Filipe Sarturi
la source
4
ajoutez aussi une description.
Shree Krishna
Comme plusieurs réponses précédentes l'ont mentionné, cela lancera une ReferenceError s'il est appelé avec une variable qui n'a jamais été déclarée. Par exemple isset(someVar), où someVarn'a jamais été déclaré. Cependant, étant donné que vous le faites eval, vous avez probablement l'intention de transmettre une chaîne . Afficher l'utilisation. Votre usage est-il prévu isset('someVar')? Si oui, cela ressemble à cette réponse précédente - qu'en est-il de votre réponse est nouvelle?
ToolmakerSteve
3
window.isset = function(v_var) {
    if(typeof(v_var) == 'number'){ if(isNaN(v_var)){ return false; }}
    if(typeof(v_var) == 'undefined' || v_var === null){ return false;   } else { return true; }
};

plus tests:

https://gist.github.com/daylik/24acc318b6abdcdd63b46607513ae073

Oleg Meshaev
la source
Comme plusieurs réponses précédentes l'ont mentionné, cela lancera une ReferenceError s'il est appelé avec une variable qui n'a jamais été déclarée.
ToolmakerSteve
3

Pour vérifier si le bloc html est existant ou non, j'utilise ce code:

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

Fournissez le chemin de l'objet sous forme de chaîne, puis vous pouvez diviser cette chaîne en chemin et résoudre hasOwnPropertyà chaque étape tout en écrasant l'objet lui-même à chaque itération.

Si vous codez dans un environnement ES6, jetez un œil à ces Ques de stackoverflow .

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
);

Gajus
la source
2

J'utilise une fonction qui peut vérifier les variables et les objets. très pratique pour travailler avec jQuery

    function _isset (variable) {
        if(typeof(variable) == "undefined" || variable == null)
            return false;
        else
            if(typeof(variable) == "object" && !variable.length) 
                return false;
            else
                return true;
    };
Евгений Кичаев
la source
Comme plusieurs réponses précédentes l'ont mentionné, cela lancera une ReferenceError s'il est appelé avec une variable qui n'a jamais été déclarée.
ToolmakerSteve
1

C'était vraiment un problème pour moi lorsque j'accédais à une propriété plus profonde d'un objet, j'ai donc créé une fonction qui retournera la valeur de la propriété si elle existe sinon elle retournera false. Vous pouvez l'utiliser pour gagner du temps,

//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
bikash.bilz
la source
1

Si vous souhaitez vérifier si un élément existe, utilisez simplement le code suivant:

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

Voici un exemple:

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>

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

Manuel PHP dit:

isset - Détermine si une variable est définie et n'est pas NULL

Et interface quelque chose comme ceci:

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

Le paramètre $varest la variable à vérifier. il peut cependant avoir n'importe quel nombre de paramètres.

isset () retourne TRUEsi var existe et a une valeur autre que NULL. FALSEautrement.

Un exemple:

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

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

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

Dans cet esprit, apparemment, il n'est pas possible d'écrire l'équivalent exact de la isset()fonction php . Par exemple, lorsque nous appelons comme ceci:

if (isset(some_var)) {

}

function issset() {
    // function definition
}

Déclencheur Javascript Uncaught ReferenceError: some_var is not defined at (file_name):line_number. La chose importante et remarquable à propos de ce comportement est que lorsque vous essayez de passer des variables inexistantes à des fonctions normales, une erreur est déclenchée.

Mais en PHP isset()ne sont pas en fait des fonctions régulières mais des constructions de langage. Cela signifie qu'ils font partie du langage PHP lui-même, ne respectent pas les règles normales des fonctions et peuvent donc éviter de déclencher une erreur pour les variables inexistantes. Ceci est important lorsque vous essayez de déterminer si une variable existe ou non. Mais en javscript, il déclenche une erreur en premier lieu par exemple appel de fonction avec des variables inexistantes.

Mon point est que nous ne pouvons pas l'écrire en tant que fonction javscript équivalente, mais nous pouvons faire quelque chose comme ça

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

Si vous voulez exactement le même effet, PHP vérifie également que la variable n'est pas NULL

Par exemple

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

Donc, nous pouvons l'incorporer dans javascript puis cela ressemble à ceci:

if (typeof some_var !== 'undefined' && some_var !== null) {
   // your code here
}
Arjun Kariyadan
la source
0

javascript isset

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
Алексей Арх
la source
0

Soyez prudent dans ES6 , toutes les solutions précédentes ne fonctionnent pas si vous voulez vérifier une déclaration d'une variable let et la déclarer, si ce n'est pas le cas

exemple

let myTest = 'text';

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

vous verrez une erreur

SyntaxError non interceptée: l'identificateur 'myTest' a déjà été déclaré

La solution était de le changer par un var

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

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

une autre solution si vous pouvez changer un let par un var, vous devez supprimer votre var

let myTest = 'text';

if(typeof myTest === "undefined") {
    myTest = 'new text'; // I remove the var declaration
}
Laurent Chaloupe
la source
-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;
        }
    }
Vano
la source