web-dev-qa-db-fra.com

JavaScript null check

J'ai rencontré le code suivant:

function test(data) {
    if (data != null && data !== undefined) {
        // some code here
    }
}

Je suis un peu nouveau dans JavaScript, mais d'après d'autres questions que j'ai lues ici, j'ai l'impression que ce code n'a pas beaucoup de sens.


En particulier, cette réponse indique que

Vous obtiendrez une erreur si vous accédez à une variable non définie dans un contexte autre que typeof.

Mise à jour: La (citation de) la réponse ci-dessus peut être trompeuse. Il faut dire "une variable non déclarée" , au lieu de "une variable non définie" .

Comme je l'ai découvert, dans les réponses par Ryan ♦ , ) maerics =, et nwellnhof , même si aucun argument n'est fourni à une fonction, ses variables pour les arguments sont toujours déclarées. Ce fait prouve également à tort le premier élément de la liste ci-dessous.


De ma compréhension, les scénarios suivants peuvent être vécus:

  • La fonction a été appelée sans argument, faisant ainsi de data une variable indéfinie et générant une erreur sur data != null.

  • La fonction a été appelée spécifiquement avec null (ou undefined) comme argument, auquel cas data != null protège déjà le code interne, rendant && data !== undefined inutile.

  • La fonction a été appelée avec un argument non nul, auquel cas elle passera trivialement à la fois data != null et data !== undefined.

Q: Est-ce que ma compréhension est correcte?


J'ai essayé ce qui suit dans la console de Firefox:

--
[15:31:31.057] false != null
[15:31:31.061] true
--
[15:31:37.985] false !== undefined
[15:31:37.989] true
--
[15:32:59.934] null != null
[15:32:59.937] false
--
[15:33:05.221] undefined != null
[15:33:05.225] false
--
[15:35:12.231] "" != null
[15:35:12.235] true
--
[15:35:19.214] "" !== undefined
[15:35:19.218] true

Je ne peux pas imaginer un cas où le data !== undefined après data != null pourrait être utile.

154
afsantos

Une "variable indéfinie" est différente de la valeur undefined.

Une variable non définie:

var a;
alert(b); // ReferenceError: b is not defined

Une variable avec la valeur undefined:

var a;
alert(a); // Alerts “undefined”

Lorsqu'une fonction prend un argument, cet argument est toujours déclaré, même si sa valeur est undefined. Il n'y aura donc pas d'erreur. Vous avez raison à propos de != null suivi de !== undefined étant inutile, cependant.

102
Ry-

En JavaScript, null est un objet singleton spécial, utile pour signaler "aucune valeur". Vous pouvez le tester par comparaison et, comme d'habitude en JavaScript, il est recommandé d'utiliser l'opérateur === pour éviter la coercition de type déroutante:

var a = null;
alert(a === null); // true

Comme @rynah le mentionne, "undefined" est un peu déroutant en JavaScript. Cependant, il est toujours prudent de tester si typeof(x) est la chaîne "indéfinie", même si "x" n'est pas une variable déclarée:

alert(typeof(x) === 'undefined'); // true

De plus, les variables peuvent avoir la "valeur indéfinie" si elles ne sont pas initialisées:

var y;
alert(typeof(y) === 'undefined'); // true

En réunissant tout cela, votre chèque devrait ressembler à ceci:

if ((typeof(data) !== 'undefined') && (data !== null)) {
  // ...

Cependant, étant donné que la variable "data" est toujours définie puisqu'il s'agit d'un paramètre de fonction formel, il n'est pas nécessaire d'utiliser l'opérateur "typeof" et vous pouvez comparer en toute sécurité directement avec la "valeur indéfinie".

function(data) {
  if ((data !== undefined) && (data !== null)) {
    // ...

Cet extrait équivaut à dire "si la fonction a été appelée avec un argument défini et non nul ..."

80
maerics

Q: La fonction a été appelée sans aucun argument, ce qui a pour effet de transformer les données en une variable non définie et de générer une erreur sur les données! = Null.

A: Oui, data sera défini sur non défini. Voir section 10.5 Instanciation de liaison de déclaration de la spéc. Mais accéder à une valeur indéfinie ne génère pas d'erreur. Vous confondez probablement cela avec l'accès à une variable non déclarée en mode strict qui génère une erreur.

Q: La fonction a été appelée spécifiquement avec null (ou indéfini), en tant qu'argument, auquel cas data! = Null protège déjà le code interne, ce qui rend && data! == non défini inutile.

Q: La fonction a été appelée avec un argument non nul, auquel cas elle transmettra trivialement les données! = Null et data! == non défini.

A: Correct. Notez que les tests suivants sont équivalents:

data != null
data != undefined
data !== null && data !== undefined

Voir section 11.9.3 Algorithme de comparaison d'égalité abstraite et section 11.9.6 Algorithme de comparaison d'égalité stricte de la spéc.

8
nwellnhof

Dans votre cas, utilisez data==null (qui est vrai UNIQUEMENT pour les valeurs null et indéfinie - sur la deuxième image, sur les lignes/colonnes null-indéfini)

function test(data) {
    if (data != null) {
        console.log('Data: ', data);
    }
}

test();          // the data=undefined
test(null);      // the data=null
test(undefined); // the data=undefined

test(0); 
test(false); 
test('something');

Ici vous avez tous ( src ):

if

enter image description here

== (sa négation ! = )

enter image description here

=== (sa négation ! == )

enter image description here

4
Kamil Kiełczewski

Je pense que tester des variables pour des valeurs inattendues n’est pas une bonne idée en général. Parce que le test en tant que votre, vous pouvez considérer comme écrivant une liste noire de valeurs interdites. Mais si vous oubliez de lister toutes les valeurs interdites? Quelqu'un, même vous, peut déchiffrer votre code en transmettant une valeur inattendue. Une approche plus appropriée s'apparente donc à une liste blanche: tester les variables uniquement pour les valeurs attendues, et non inattendues. Par exemple, si vous vous attendez à ce que la valeur de données soit une chaîne, remplacez ceci:

function (data) {
  if (data != null && data !== undefined) {
    // some code here
    // but what if data === false?
    // or data === '' - empty string?
  }
}

faire quelque chose comme ça:

function (data) {
  if (typeof data === 'string' && data.length) {
    // consume string here, it is here for sure
    // cleaner, it is obvious what type you expect
    // safer, less error prone due to implicit coercion
  } 
}
3
user6748331

typeof foo === "undefined" est différent de foo === undefined, ne les confondez jamais. typeof foo === "undefined" est ce dont vous avez vraiment besoin. Utilisez également !== à la place de !=

Donc, la déclaration peut être écrite comme

function (data) {
  if (typeof data !== "undefined" && data !== null) {
    // some code here
  }
}

Edit:

Vous ne pouvez pas utiliser foo === undefined pour les variables non déclarées.

var t1;

if(typeof t1 === "undefined")
{
  alert("cp1");
}

if(t1 === undefined)
{
  alert("cp2");
}

if(typeof t2 === "undefined")
{
  alert("cp3");
}

if(t2 === undefined) // fails as t2 is never declared
{
  alert("cp4");
}
1
user2396441

Le moyen simple de faire votre test est:

function (data) {
    if (data) { // check if null, undefined, empty ...
        // some code here
    }
}
1
Kadiri