web-dev-qa-db-fra.com

Pourquoi y a-t-il une valeur `null` en JavaScript?

En JavaScript, il existe deux valeurs qui disent en gros «Je n’existe pas» - undefined et null.

Une propriété à laquelle un programmeur n'a rien assigné sera undefined, mais pour qu'une propriété devienne null, null doit lui être explicitement affectée.

J'ai déjà pensé qu'il était nécessaire d'utiliser null car undefined est une valeur primitive et null un objet. Ce n'est pas le cas, même si typeof null donnera 'object': en fait, les deux sont des valeurs primitives - ce qui signifie que ni undefined ni null ne peuvent être retournés à partir d'une fonction constructeur car ils seront tous deux convertis en un objet vide dans les constructeurs).

Ils ont également tous deux évaluer à false dans des contextes booléens. La seule différence réelle à laquelle je puisse penser est que l’un évalue NaN, l’autre 0 dans des contextes numériques.

Alors pourquoi y a-t-il à la fois undefined et null si cela confond simplement les programmeurs qui vérifient de manière incorrecte null en essayant de savoir si une propriété a été définie ou non?

Ce que j'aimerais savoir, c'est si quelqu'un a un exemple raisonnable dans lequel il est nécessaire d'utiliser null, ce qui ne pourrait pas être exprimé en utilisant undefined à la place.

Donc, le consensus général semble être que undefined signifie «il n'y a pas une telle propriété» alors que null signifie «la propriété existe, mais ne contient aucune valeur».

Je pourrais vivre avec cela si les implémentations JavaScript imposaient ce comportement - mais undefined est une valeur primitive parfaitement valide, de sorte qu'il peut facilement être affecté à des propriétés existantes pour rompre ce contrat. Par conséquent, si vous voulez vous assurer qu'une propriété existe, vous devez quand même utiliser l'opérateur in ou hasOwnProperty(). Encore une fois: quelle est l’utilité pratique de séparer les valeurs undefined et null?

J'utilise réellement undefined lorsque je veux supprimer les valeurs des propriétés qui ne sont plus utilisées mais que je ne veux pas delete. Devrais-je utiliser null à la place?

107
Christoph

La question n'est pas vraiment "pourquoi y a-t-il une valeur nulle dans JS"? Il existe une sorte de valeur nulle dans la plupart des langues et elle est généralement considérée comme très utile.

La question est: "pourquoi y a-t-il une undefined value dans JS". Principaux endroits où il est utilisé:

  1. lorsque vous déclarez 'var x;' mais ne lui attribuez pas, x est indéfini;
  2. quand votre fonction reçoit moins d'arguments qu'elle n'en déclare;
  3. lorsque vous accédez à une propriété d'objet inexistant.

'null' aurait certainement aussi bien fonctionné pour (1) et (2) *. (3) devrait vraiment lancer immédiatement une exception, et le fait que ce ne soit pas le cas, renvoyant cet étrange 'indéfini' qui échouera ultérieurement, est une source importante de problèmes de débogage.

*: vous pouvez également dire que (2) devrait générer une exception, mais vous devrez alors fournir un mécanisme plus explicite et meilleur pour les arguments par défaut/variables.

Cependant, JavaScript n'avait à l'origine aucune exception, ni aucun moyen de demander à un objet s'il avait un membre sous un certain nom - le seul moyen était (et reste parfois) d'accéder au membre et de voir ce que vous obtenez. Étant donné que 'null' avait déjà un but et que vous souhaitiez peut-être lui affecter un membre, une valeur hors bande différente était requise. Nous avons donc «indéfini», c'est problématique, comme vous l'avez souligné, et c'est une autre «fonctionnalité» JavaScript très intéressante, dont nous ne pourrons jamais nous débarrasser.

En fait, j'utilise undefined lorsque je veux supprimer les valeurs des propriétés qui ne sont plus utilisées mais que je ne veux pas supprimer. Devrais-je utiliser null à la place?

Oui. Conservez 'indéfini' en tant que valeur spéciale pour signaler quand d'autres langues peuvent générer une exception.

'null' est généralement préférable, sauf sur certaines interfaces DOM IE où définir quelque chose sur 'null' peut vous donner une erreur. Dans ce cas, la définition de la chaîne vide a souvent tendance à fonctionner.

65
bobince

Mieux décrit ici , mais en résumé:

indéfini est l’absence de type et de valeur et null est l’absence de valeur.

De plus, si vous faites des comparaisons simples, vous aurez raison, elles se ressemblent. Mais essayez ===, qui compare à la fois le type et la valeur, et vous remarquerez la différence.

36
Eddie Parker

Je ne pense pas qu'il y ait de raison d'avoir à la fois null et undefined, car la seule raison que beaucoup de gens ont suggérée ("undefined signifie qu'il n'y a pas une telle variable/propriété") n'est pas valide, du moins en JavaScript. undefined ne peut pas vous dire si la variable/propriété existe ou non.

console.log(foo);               // "ReferenceError: foo is not defined"
                                // foo does not exist
var foo;
console.log(foo);               // "undefined", a different response
console.log(foo === undefined); // "true", but it does exist

var obj = {};
console.log(obj.hasOwnProperty("foo")); // "false", no such property
obj.foo = undefined;
console.log(obj.hasOwnProperty("foo")); // "true", it exists and has the value "undefined"
console.log(obj.foo === undefined);     // "true", but it does exist

obj.bar = "delete me";
obj.bar = undefined;
console.log(obj.hasOwnProperty("bar")); // "true", not actually deleted
delete obj.bar;
console.log(obj.hasOwnProperty("bar")); // "false", deleted

Comme vous pouvez le constater, la vérification de foo === undefined ne vous indique pas si foo existe et le paramétrage de obj.bar = undefined ne supprime pas réellement bar.

Il se peut que l'intention originale de l'auteur de JavaScript soit que undefined représente "non-existence". Cependant, la mise en œuvre ne s'est pas passée ainsi.

16
Lei Zhao

Il est tout à fait possible d'avoir besoin des deux. Par exemple, si vous interrogez WMI, il est tout à fait possible qu'une classe renvoie des propriétés qui ont une valeur null. Ils sont définis, ils arrivent juste à être nuls à l'époque.

6
EBGreen

Je pense que votre conclusion selon laquelle JavaScript définit undefined comme "il n'y a pas de telle propriété" et null comme "la propriété n'a pas de valeur" est parfaitement correcte. Et dans un langage aussi dynamique que JavaScript, il s'agit d'une distinction très importante. L'utilisation de la frappe de canard signifie que nous devons être en mesure de différencier une propriété qui n'existe pas et qui n'a pas de valeur. C'est notre principal moyen de dériver des informations de type. dans un langage à typage statique, il existe une distinction nette entre un champ nul et un champ inexistant. En JavaScript, ce n'est pas différent. Cependant, il est vérifié au moment de l'exécution et peut être modifié jusque-là.

Je vais devoir convenir que la mise en œuvre est étrange, car la distinction est souvent floue. Cependant, je pense qu'en JavaScript la distinction est importante. Et pouvoir assigner undefined est essentiel.

Je me souviens avoir lu un billet de blog il y a quelque temps sur un RPG en ligne écrit en JavaScript. Il utilisait des exemples dans lesquels des objets étaient créés en tant que copies d'instances existantes plutôt que des prototypes (classes, fonctions, etc.), puis modifiés. Cela m'a vraiment fait comprendre à quel point undefined pouvait être puissant lors de la modification d'objets existants, mais je ne me souviens plus qui l'a écrit.

6
Jack Ryan

En tant que programmeur Java, je vois une énorme différence entre undefined et null. Codage de JavaScript, pas tellement, parce que JavaScript n'est pas fortement typé, et les différences entre undefined et null sont estompées par les conversions automatiques fréquemment effectuées par l'exécution BTW, je profite souvent de ces conversions; ils rendent mon code JS plus compact et lisible.

Pour répondre à votre question, non défini signifie qu'une valeur n'a jamais été définie. En pratique, cela indique généralement un bogue. Si yourObject.property n'est pas défini, cela signifie que vous n'avez pas défini la propriété pour une raison quelconque ou que je recherche quelque chose qui n'existe pas du tout. C'est un problème réel lorsque vous travaillez sur un projet avec plusieurs codeurs.

null signifie que "aucune valeur" n'a été explicitement définie. Concrètement, vous me parlez de la propriété, peut-être qu’elle n’est pas utilisée dans ce contexte ou qu’une valeur n’a pas encore été déterminée.

En Java, toute tentative d'accès à un champ non défini entraînera toujours une exception. En fait, le compilateur peut être fait pour vous en avertir dans votre code.

3
Steve11235

Sémantiquement, ils signifient différentes choses. Le type null a exactement une valeur dans son domaine, null et une propriété peut être affectée à cette valeur spécifique. Undefined représente un manque distinct de toute valeur attribuée.

3
AnthonyWJones

Essayez cet exemple:

<html>
<head>
    <script type="text/javascript">
        function ShowObjProperties(obj) {
            var property, propCollection = "";

            for(property in obj) {
                propCollection += (property + ": " + obj[property] + "\n");
            }

            alert(propCollection);
        }

        var obj = {
            userid: 3,
            name: 'me!',
            speak: function() { alert('Hi! My name is ' + this.name + ' and my ID is ' + this.userid + '.'); }
        }

        //Shows all properties
        ShowObjProperties(obj);

        //The Speak function is no longer in the list!
        delete obj.speak;
        alert(typeof obj.speak);
        ShowObjProperties(obj);

        //The UserID is still listed, it just has no value!
        obj.userid = null;
        ShowObjProperties(obj);
    </script>
</head>
<body>

</body>
</html>

Je pense qu'il y a une utilisation très réelle de 2 types différents ici.

0
EndangeredMassa

c'est une fonctionnalité linguistique importante si vous programmez votre programme dans le paradigme du javascript.

// a key exists as a placeholder for something
if(obj[name] === null) 
// no key exists int eh hashtable that is in this object
if(obj[name] === undefined)

ceci est très utile si vous traitez avec un ensemble de données nécessitant une valeur représentant «rien» pour indiquer une action différente de l'utilisation de «rien» pour indiquer l'action par défaut.

filter_func_pt = {
  date:function(d){ return Math.round(d.getTime()/1000);},
  user: null,
}

function transform(obj){
    var ret = {};
    for( var prop in obj){
       var f = filter_func_pt[prop];
       if(f)
          ret[prop] = f(obj);
       else if(filter_func_pt[prop] === null)
         continue;
       else
         ret[prop] == obj;
    }
  return ret;
}

var a = {
   date: new Date(),
   user: 'sam'
   votes: [23, 41, 55] 
};

var b = transform(a);

/* b = {
 *    date: 1298582417
 *    votes: [23, 41, 55]
 * }
 */

dans le code ci-dessus, le mot-clé null et le serveur undefined sont des objectifs très clairs et différents. la recherche non trouvée dans l'objet filter_func_pt qui retourne undefined signifie qu'il faut ajouter la propriété à l'objet de retour tel quel, alors qu'une valeur null indique que la valeur doit être masquée et non ajoutée, et la présence de toute valeur vraie dans ce cas représente une fonction utilisée pour transformer la valeur avant de l'ajouter à l'objet ret .

0
Fire Crow

Il s’agit de la nature dynamique javascript. 

Les choses peuvent être indéfinies pour pouvoir être ajoutées ultérieurement. C'est sans doute pourquoi le javascript est si puissant et extensible.

0

null is beautiful

comme tous les autres types de script en direct.

cite: En JavaScript, il y a deux valeurs qui disent en gros «je ne le fais pas exist '- indéfini et null.

Pourquoi voudriez-vous dire des choses incorrectes?!

"null" is "Objet vide" comme "0" est un "nombre vide". 0, n’est rien - même s’il existe en tant que type d’une chose de nombre .null est bien sûr également vide mais "c’est" et c’est une chose bien définie d’un type d'objet.

Il est courant de parler de ces types de "types", quand ils ne le sont pas. En fait, ce sont des "catégories". Mais c'est fini maintenant. 

Nous nous en tiendrons donc à dire que "null" est un type d'objet sans sorte. Et "null" dit "J'existe beaucoup [!], Mais je n'ai pas de contenu de mon genre".

Alors que undefined ne possède ni le type ni le type, undefined étant également sa définition de type. Un type indéfini d'un type devient sa typologie distinctive . Une sorte de question [il n'existe "rien" et comment définissez-vous "rien"?].

cite: undefined ni null peuvent être retournés à partir d'une fonction constructeur, comme les deux seront convertis en un objet vide

Vous avez réussi à dire encore une fois une chose incorrecte. Bien sûr que non, le "non défini" n'est pas un objet, mais un simple jeton que nous, humains, comprenons; mais contrairement à cela, null est - et cela vous indique que: son type est correct, mais le type que vous recherchez n'y est pas contenu, ou du moins, pas pour le moment. Venez nous rendre visite plus tard quand nous y avons assigné un objet.

citer: La seule différence réelle à laquelle je peux penser est que l’on évalue à NaN, l'autre à 0 dans les contextes numériques.

Cela fait l’essentiel de leur distinction fondamentale, comme indiqué ci-dessus: non défini est un signe pur et comme il est composé du même matériel "génétique" que ses parents distants: les chaînes, l’opération [+ non défini] -convertissez-le en NaN, de la même manière null se transformera naturellement en un type correct 0\Number, et contrairement à undefined qui se transformera en une chaîne (! qui n'est pas vide!) et c'est exactement pourquoi donne plutôt NaN. Où: + undefined >> + "undefined" >> NaN. Étant donné que le contexte numérique attend une valeur explicite.

Tandis que le contexte booléen attend une référence - ne trouve rien à convertir et renvoie "faux".

Coupons à travers maintenant ... 

cite: Encore une fois: quelle est l’utilité pratique de valeurs distinctes pour non défini et nul?

Je vais essayer de vous donner que deux exemples empiriques et espère suffire

oElement.onclick >> null

// signifie -la propriété existe; sa valeur attendue est de Type: Object, et oElement prend en charge l'événement "onclick"!

oElement.innerText >> ""

// signifie - la propriété existe; sa valeur attendue est de Type: String, ce qui signifie que oElement prend en charge la propriété "innerText".

dans les deux cas - si vous recevez "indéfini", cela signifie que la propriété n'existe pas; n'est pas pris en charge ou a une implémentation incorrecte (fournisseur).

Restez au froid et amusez-vous.

0
user1170379

après avoir lu une discussion époustouflante sur undefined vs null, peu de recherches sur Google m'ont amené à Mozilla Documentations https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null il est mentionné - null est souvent récupéré à un endroit où un objet peut être attendu mais aucun objet n’est pertinent. 

Is not est similaire au modèle d'objet Null https://en.wikipedia.org/wiki/Null_object_pattern

Donc, je suppose que cela a du sens d’avoir le type de données Null.

La documentation est également mentionnée sous la forme Typeof null // "objet" (pas "null" pour des raisons héritées du passé)

Vous ne savez pas quelles sont les raisons de l'héritage

0
Vishal Bhandare