Question typeof! == "non défini" vs! = null


Je vois souvent du code JavaScript qui vérifie les paramètres non définis, etc. de cette façon:

if (typeof input !== "undefined") {
    // do stuff
}

Cela semble une sorte de gaspillage, car il implique à la fois une recherche de type et une comparaison de chaînes, sans parler de sa verbosité. C'est nécessaire parce que "undefined" pourrait être renommé, cependant. Ma question est la suivante: comment ce code est-il meilleur que cette approche:

if (null != input) {
    // do stuff
}

Autant que je sache, vous ne pouvez pas redéfinir null, donc il ne va pas se briser de manière inattendue. Et, à cause de la contrainte de type de l'opérateur! =, Cela vérifie à la fois les valeurs indéfinies et les valeurs NULL ... ce qui est souvent exactement ce que vous voulez (par exemple, pour les paramètres de fonction facultatifs). Pourtant, cette forme ne semble pas répandue, et JSLint vous crie même pour avoir utilisé l'opérateur evil! =. Pourquoi est-ce considéré comme un mauvais style?


422
2018-04-24 03:26


origine


Réponses:


typeof permet que l'identifiant n'ait jamais été déclaré auparavant. Donc, c'est plus sûr à cet égard:

if(typeof neverDeclared == "undefined") //no errors

if(neverDeclared == null) //throws ReferenceError: neverDeclared is not defined

616
2018-04-24 03:37



Si la variable est déclarée (soit avec le var mot-clé, comme argument de fonction ou comme variable globale), je pense que la meilleure façon de le faire est:

if (my_variable === undefined)

jQuery le fait, alors ça me suffit :-)

Sinon, vous devrez utiliser typeof éviter un ReferenceError.

Si vous souhaitez redéfinir undefined, vous pouvez envelopper votre code comme ceci:

(function(undefined){
    // undefined is now what it's supposed to be
})();

45
2018-04-24 03:59



bonne façon:

if(typeof neverDeclared == "undefined") //no errors

Mais le meilleur moyen est de vérifier via:

if(typeof neverDeclared === typeof undefined) //also no errors and no strings

23
2018-05-09 15:21



Vous ne devriez pas vraiment vous inquiéter de la renommée indéfinie. Si quelqu'un renomme non défini, vous rencontrerez beaucoup plus d'ennuis que quelques-uns seulement si les contrôles échouent. Si vous voulez vraiment protéger votre code, enveloppez-le dans un IFFE (expression de la fonction invoquée immédiatement) comme ceci:

(function($, Backbone, _, undefined) {
    //undefined is undefined here.
})(jQuery, Backbone, _);

Si vous travaillez avec des variables globales (ce qui est déjà faux) dans l'environnement d'un navigateur, je vérifierais pour non défini comme ceci:

if(window.neverDefined === undefined) {
    //Code works
}

Étant donné que les variables globales font partie de l'objet window, vous pouvez simplement vérifier par rapport à undefined au lieu de lancer une chaîne et de comparer des chaînes.

De plus, pourquoi vos variables ne sont-elles pas définies? J'ai vu beaucoup de code où ils vérifient une existence de variables et effectuent une action basée sur cela. Pas une fois j'ai vu où cette approche a été correcte.


12
2017-10-05 09:41



Si vous êtes vraiment inquiet à propos de la redéfinition non définie, vous pouvez vous protéger contre cela avec une méthode d'assistance comme celle-ci:

function is_undefined(value) {
   var undefined_check; // instantiate a new variable which gets initialized to the real undefined value
   return value === undefined_check;
}

Cela fonctionne parce que quand quelqu'un écrit undefined = "foo" il ne laisse que le prénom  undefined référence à une nouvelle valeur, mais il ne change pas la valeur réelle de undefined.


5
2018-04-24 03:41



Vous pouvez également utiliser l'opérateur void pour obtenir une valeur indéfinie:

if (input !== void 0) {
    // do stuff    
}

(Et oui, comme indiqué dans une autre réponse, cela génère une erreur si la variable n'a pas été déclarée, mais ce cas peut souvent être exclu soit par inspection de code, soit par refactorisation de code, par exemple en utilisant window.input !== void 0 pour tester des variables globales ou en ajoutant var input.)


4
2018-03-09 11:08



J'ai effectivement rencontré si (typeof input !== 'undefined') dans ce scénario où il est utilisé pour fournir des paramètres de fonction par défaut:

function greet(name, greeting) {
  name = (typeof name !== 'undefined') ?  name : 'Student';
  greeting = (typeof greeting !== 'undefined') ?  greeting : 'Welcome';

  return `${greeting} ${name}!`;
}

greet(); // Welcome Student!
greet('James'); // Welcome James!
greet('Richard', 'Howdy'); // Howdy Richard!

ES6 offre de nouvelles façons d’introduire les paramètres de fonction par défaut de la manière suivante:

function greet(name = 'Student', greeting = 'Welcome') {
  return `${greeting} ${name}!`;
}

greet(); // Welcome Student!
greet('James'); // Welcome James!
greet('Richard', 'Howdy'); // Howdy Richard!

C'est moins verbeux et plus propre que la première option.


0
2018-06-13 20:35



if (input == undefined) { ... }

fonctionne très bien. Ce n'est bien sûr pas un null comparaison, mais je trouve généralement que si je dois faire la distinction entre undefined et null, Je dois plutôt faire la distinction entre undefined et juste n'importe quelle valeur fausse, donc

else if (input) { ... }

le fait.

Si un programme redéfinit undefined c'est vraiment braindead quand même.

La seule raison que je peux penser était pour la compatibilité IE4, il n'a pas compris le undefined mot-clé (qui n'est pas réellement un mot-clé, malheureusement), mais bien sûr des valeurs pourraient être  undefined, donc vous deviez avoir ceci:

var undefined;

et la comparaison ci-dessus fonctionnerait très bien.

Dans votre deuxième exemple, vous avez probablement besoin de doubles parenthèses pour rendre la peluche heureuse?


-7
2018-04-24 03:50