Puis-je définir des variables sur undefined ou passer undefined comme argument?

304

Je suis un peu confus au sujet du JavaScript undefinedet des nullvaleurs.

Que fait-il if (!testvar)réellement? Teste-t-il pour undefinedet nullou juste undefined?

Une fois qu'une variable est définie, puis-je la réinitialiser undefined(donc supprimer la variable)?

Puis-je passer undefineden paramètre? Par exemple:

function test(var1, var2, var3) {

}

test("value1", undefined, "value2");
UN J.
la source
Rép

Réponses:

514

Je suis un peu confus au sujet de Javascript non défini et nul.

Ne soyez pas confus null. Il a généralement un sens et se comporte de manière similaire aux concepts des autres langages de script des objets hors bande «null», «nil» ou «None».

undefined, d'autre part, est une bizarrerie JavaScript étrange. C'est un objet singleton qui représente des valeurs hors bande, essentiellement un deuxième similaire mais différent null. Cela revient:

  1. Lorsque vous appelez une fonction avec moins d'arguments que la liste d'arguments dans les functionlistes d'instructions, les arguments non passés sont définis sur undefined. Vous pouvez tester cela avec par exemple:

    function dosomething(arg1, arg2) {
        if (arg2===undefined)
        arg2= DEFAULT_VALUE_FOR_ARG2;
        ...
    }

    Avec cette méthode, vous ne pouvez pas faire la différence entre dosomething(1)et dosomething(1, undefined); arg2sera la même valeur dans les deux. Si vous devez faire la différence, vous pouvez regarder arguments.length, mais faire des arguments facultatifs comme celui-ci n'est généralement pas très lisible.

  2. Lorsqu'une fonction n'a pas return value;, elle revient undefined. Il n'est généralement pas nécessaire d'utiliser un tel résultat de retour.

  3. Lorsque vous déclarez une variable en ayant une var ainstruction dans un bloc, mais que vous ne lui avez pas encore attribué de valeur, c'est le cas undefined. Encore une fois, vous ne devriez pas vraiment avoir besoin de vous y fier.

  4. L' typeofopérateur effrayant retourne 'undefined'lorsque son opérande est une simple variable qui n'existe pas, au lieu de lancer une erreur comme cela se produirait normalement si vous tentiez de vous y référer. (Vous pouvez également lui donner une simple variable entourée de parenthèses, mais pas une expression complète impliquant une variable inexistante.) Pas très utile non plus.

  5. C'est le sujet controversé. Lorsque vous accédez à une propriété d'un objet qui n'existe pas, vous n'obtenez pas immédiatement une erreur comme dans toutes les autres langues. Au lieu de cela, vous obtenez un undefinedobjet. (Et puis, lorsque vous essayez d'utiliser cet undefinedobjet plus tard dans le script, il se passera de manière étrange, ce qui est beaucoup plus difficile à retrouver que si JavaScript venait de lancer une erreur tout de suite.)

    Ceci est souvent utilisé pour vérifier l'existence de propriétés:

    if (o.prop!==undefined) // or often as truthiness test, if (o.prop)
       ...do something...

    Cependant, comme vous pouvez attribuer undefinedcomme n'importe quelle autre valeur:

    o.prop= undefined;

    cela ne détecte pas réellement si la propriété est là de manière fiable. Mieux vaut utiliser l' inopérateur, qui n'était pas dans la version originale Netscape de JavaScript, mais est disponible partout maintenant:

    if ('prop' in o)
        ...

En résumé, undefinedest un gâchis spécifique à JavaScript, qui déroute tout le monde. En dehors des arguments de fonction facultatifs, où JS n'a pas d'autre mécanisme plus élégant, undefinedil convient d'éviter. Cela n'aurait jamais dû faire partie de la langue; nullaurait très bien fonctionné pour (2) et (3), et (4) est une erreur qui n'existe que parce qu'au début JavaScript n'avait pas d'exceptions.

que fait-il if (!testvar)réellement? Teste-t-il pour indéfini et nul ou simplement indéfini?

Un tel test vérifie « truthiness » contre false, undefined, null, 0, NaNet des chaînes vides. Mais dans ce cas, oui, c'est vraiment de undefinedcela qu'il s'agit. OMI, il devrait être plus explicite à ce sujet et dire if (testvar!==undefined).

une fois qu'une variable est définie, puis-je la réinitialiser à undefined (donc supprimer la variable).

Vous pouvez certainement lui attribuer undefined, mais cela ne supprimera pas la variable. Seul l' delete object.propertyopérateur enlève vraiment les choses.

deleteest vraiment destiné aux propriétés plutôt qu'aux variables en tant que telles. Les navigateurs vous permettront de vous en sortir delete variable, mais ce n'est pas une bonne idée et ne fonctionnera pas en mode strict d'ECMAScript Fifth Edition. Si vous souhaitez libérer une référence à quelque chose afin qu'il puisse être récupéré, il serait plus habituel de le dire variable= null.

puis-je passer indéfini comme paramètre?

Oui.

bobince
la source
10
Quelle réponse fantastique. Je viens d'échouer au test JavaScript: perfectionkills.com/javascript-quiz Plus tard, je vais relire votre réponse et recommencer le test!
Skilldrick
1
fixe, ta. (J'ai tendance à ne pas trop m'inquiéter de la réaffectation, car il y a tellement de choses qu'un script pourrait redéfinir pour tout gâcher que le cas général est impossible à résoudre.)
bobince
2
@bobince undefinedest un objet singleton? Que voulez-vous dire? C'est une valeur primitive et non un objet.
Šime Vidas
2
@Hortitude: C'est le point (4). Je ne le ferais généralement pas typeof foo=='undefined'; il a tendance à être utilisé pour (4a) le reniflement global, auquel cas je préférerais être explicite et dire 'foo' in window, ou (4b) tester par rapport à la valeur undefinedelle-même, auquel cas je préférerais être lisible et dire foo===undefined. En théorie, les tests typeofcontre 'undefined'pourraient avoir un cas d'utilisation que d'autres constructions ne pourraient pas fournir: détecter l'existence de variables locales. Cependant, en réalité, vous savez presque toujours quelles variables sont déclarées locales.
bobince
4
Une mise en garde avec # 2, généralement une fonction sans returninstruction renvoie undefined, mais si la fonction est un constructeur (invoqué avec l' newopérateur), elle renverra le nouvel objet (la valeur de l' thisintérieur du constructeur) malgré l'absence d'une returninstruction. console.log((function (){}()));retourne undefined. console.log((new function (){}()));renvoie un objet.
Code inutile
18

Vous ne pouvez pas (ne devriez pas?) Définir quoi que ce soit comme indéfini, car la variable ne serait plus indéfinie - vous venez de la définir en quelque chose.

Vous ne pouvez pas (ne devriez pas?) Passer undefinedà une fonction. Si vous souhaitez transmettre une valeur vide, utilisez nullplutôt.

L'instruction if(!testvar)vérifie les valeurs booléennes true / false, celle-ci teste si elle est testvarévaluée false. Par définition, nullet undefinedne doit pas être évalué ni comme trueni false, mais JavaScript est évalué nullcomme falseet donne une erreur si vous essayez d'évaluer une variable non définie.

Pour tester correctement undefinedou nullutiliser ces éléments:

if(typeof(testvar) === "undefined") { ... }

if(testvar === null) { ... }
Tatu Ulmanen
la source
1
Le triple égal vérifie également le type, donc aucune contrainte de type n'est effectuée. Douglas Crockford déconseille l'utilisation des opérateurs de coercition ( ==et !=).
Skilldrick
3
Vous pouvez définir quelque chose comme non défini. var a= undefined. Tu peux passer fn(undefined). Si vous souhaitez trouver la différence entre une propriété non définie pd'un objet oet une propriété pdéfinie et définie sur undefined, vous devez utiliser l' 'p' in oopérateur.
bobince
1
Y a-t-il une raison pour laquelle il ne faut pas tester testvar === undefinedplutôt que le plus compliqué typeof(testvar) === "undefined"?
ddaa
4
Il existe une autre bonne raison d'utiliser un typeoftest pour des variables non définies: contrairement à null, il undefineds'agit simplement d'une propriété de l'objet global et peut lui-même être redéfini. Il ne prend qu'un style de codage particulier et un signe égal manquant et undefinedest modifié en silence:if (undefined = someVar) {...}
Tim Down
1
@IanGrainger: ECMAScript 5 (implémenté dans les versions actuelles de tous les navigateurs) corrige principalement cela en créant undefinedune propriété immuable de l'objet global, il est donc plus sûr qu'auparavant. Cependant, il est toujours possible de définir une variable mutable appelée undefineddans une fonction, de sorte que le problème ne s'est pas entièrement résolu.
Tim Down du
13

La différence fondamentale est que undefinedet nullreprésentent différents concepts.

Si seulement nullétait disponible, vous ne seriez pas en mesure de déterminer si elle a nullété définie intentionnellement comme valeur ou si la valeur n'a pas encore été définie, sauf si vous avez utilisé une capture d'erreur lourde: par exemple

var a;

a == null; // This is true
a == undefined; // This is true;
a === undefined; // This is true;

Cependant, si vous définissez intentionnellement la valeur sur null, une égalité stricte avec undefinedéchoue, vous permettant ainsi de faire la différence entre les valeurs nullet undefined:

var b = null;
b == null; // This is true
b == undefined; // This is true;
b === undefined; // This is false;

Consultez la référence ici au lieu de vous fier à des gens qui disent des ordures avec dédain comme "En résumé, undefined est un gâchis spécifique à JavaScript, ce qui déroute tout le monde". Tout simplement parce que vous êtes confus, cela ne signifie pas que c'est un gâchis.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined

Ce comportement est pas spécifique à JavaScript et il complète le concept généralisé qu'un résultat booléen peut être true, falseinconnu ( null), aucune valeur ( undefined), ou quelque chose a mal tourné ( error).

http://en.wikipedia.org/wiki/Undefined_value

Todd
la source
Et nullaurait toujours fonctionné très bien. a == nullest trueparce que la contrainte de type Javascript.
sleepwalkerfx
11

La meilleure façon de vérifier une valeur nulle est

if ( testVar !== null )
{
    // do action here
}

et pour indéfini

if ( testVar !== undefined )
{
    // do action here
}

Vous pouvez attribuer une variable avec undefined.

testVar = undefined;
//typeof(testVar) will be equal to undefined.
rahul
la source
1
La meilleure façon de vérifier les valeurs nulles est d'utiliser !==, pas!=
MBO
6

OUI, vous pouvez, car indéfini est défini comme indéfini.

console.log(
   /*global.*/undefined === window['undefined'] &&
   /*global.*/undefined === (function(){})() &&
   window['undefined']  === (function(){})()
) //true

ton cas:

test("value1", undefined, "value2")

vous pouvez également créer votre propre variable non définie:

Object.defineProperty(this, 'u', {value : undefined});
console.log(u); //undefined

la source
5

Pour répondre à votre première question, l'opérateur not ( !) contraindra tout ce qui lui est donné en valeur booléenne. Alors null, 0, false, NaNet ""(chaîne vide) apparaissent tous faux.

Skilldrick
la source
Et aussi une chaîne vide et NaN (Pas un nombre)
MBO
undefinedn'apparaîtra pas false, il générera une erreur 'n'est pas défini'.
Tatu Ulmanen
Tatu Ulmanen: pas vrai. if (undefined) {/* Do stuff*/}ne donnera pas d'erreur, car undefinedexiste en tant que propriété de l'objet global. Ce qui donnera une erreur est quelque chose commeif (someUndeclaredVariable) {/* Do stuff*/}
Tim Down
2

JavaScript, comment définir une variable sur undefined en ligne de commande:

Définissez une variable sur undefined dans le jsterminal de ligne de commande javascript fourni avec Java sur Ubuntu 12.10.

el@defiant ~ $ js

js> typeof boo
"undefined"

js> boo
typein:2: ReferenceError: boo is not defined

js> boo=5
5

js> typeof boo
"number"

js> delete(boo)
true

js> typeof boo
"undefined"

js> boo
typein:7: ReferenceError: boo is not defined

Si vous définissez une variable sur undefined dans un javascript:

Mettez ceci dans myjs.html:

<html>
<body>
    <script type="text/JavaScript">
        document.write("aliens: " + aliens);
        document.write("typeof aliens: " + (typeof aliens));
        var aliens = "scramble the nimitz";
        document.write("found some aliens: " + (typeof aliens));
        document.write("not sayings its aliens but... " + aliens);
        aliens = undefined;
        document.write("aliens deleted");
        document.write("typeof aliens: " + (typeof aliens));
        document.write("you sure they are gone? " + aliens);
    </script>
</body>
</html>

Il imprime ceci:

aliens: undefined
typeof aliens: undefined
found some aliens: string
not sayings its aliens but... scramble the nimitz
aliens deleted
typeof aliens: undefined
you sure they are gone? undefined

AVERTISSEMENT! Lorsque vous définissez votre variable sur undefined, vous définissez votre variable sur une autre variable. Si une personne sournoise s'exécute, undefined = 'rm -rf /';chaque fois que vous définissez votre variable sur undefined, vous recevrez cette valeur.

Vous vous demandez peut-être comment je peux générer les extraterrestres à valeur indéfinie au début et le faire fonctionner. C'est à cause du levage javascript: http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

Eric Leschinski
la source
2

Essaye ça:

// found on UglifyJS
variable = void 0;
Cqq Cqq
la source
0

Le for if (something)et if (!something)est couramment utilisé pour vérifier si quelque chose est défini ou non. Par exemple:

if (document.getElementById)

L'identifiant est converti en valeur booléenne, il undefinedest donc interprété comme false. Il existe bien sûr d'autres valeurs (comme 0 et '') qui sont également interprétées comme false, mais soit l'identifiant ne devrait pas raisonnablement avoir une telle valeur, soit vous êtes satisfait de traiter une telle valeur de la même manière que non définie.

Javascript a un deleteopérateur qui peut être utilisé pour supprimer un membre d'un objet. Selon l'étendue d'une variable (c'est-à-dire si elle est globale ou non), vous pouvez la supprimer pour la rendre indéfinie.

Il n'y a aucun undefinedmot-clé que vous pouvez utiliser comme littéral non défini. Vous pouvez omettre des paramètres dans un appel de fonction pour les rendre indéfinis, mais cela ne peut être utilisé qu'en envoyant moins de paramètres à la fonction, vous ne pouvez pas omettre un paramètre au milieu.

Guffa
la source
0

Juste pour le plaisir, voici un moyen assez sûr d'affecter "non affecté" à une variable. Pour que cela ait une collision, il faudrait que quelqu'un ait ajouté au prototype d'Object avec exactement le même nom que la chaîne générée aléatoirement. Je suis sûr que le générateur de chaînes aléatoires pourrait être amélioré, mais je viens de prendre une de cette question: Générer des chaînes / caractères aléatoires en JavaScript

Cela fonctionne en créant un nouvel objet et en essayant d'accéder à une propriété sur celui-ci avec un nom généré aléatoirement, ce qui, nous supposons, n'existera pas et aura donc la valeur indéfini.

function GenerateRandomString() {
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for (var i = 0; i < 50; i++)
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

var myVar = {}[GenerateRandomString()];
rdans
la source