2012-07-12 6 views
8

de cadrage Javascript local Si je fais ceci:question

var a = 0; 

(function() { 
    var a = a; //want to make local a = global a 
    ++a; 
    console.log("fn",a); 
})(); 

console.log(a);​ 

La sortie est:

fn NaN 
0 

Pourquoi a l'intérieur de la fonction d'auto exécution deviennent NaN?

Je sais que cela fonctionne très bien si je fais:

(function() { 
    var b = a; 
    ++b; 
    console.log("fn",b); // fn 1 
})(); 

Mais si je vais le chemin de la première version, il a la question NaN.

Pourquoi cela se produit-il?

+0

Je ne sais pas pourquoi il fait ça, mais j'essayé d'utiliser 'var a = window.a' et il comporte de façon appropriée – Ibu

+0

@Ibu hmmm qui est étrange ... – Neal

+0

parce que toutes les variables globales sont dans la portée de la fenêtre – jagm

Répondre

10

est réellement var a; a = a; en raison de levage variable. Cela signifie qu'au moment de l'affectation, l'ancien a est déjà masqué par le nouveau (undefined).

La meilleure façon d'éviter les problèmes de ce genre passe la valeur en tant que paramètre:

(function (a) { 
    ++a; 
    console.log("fn",a); 
})(a); 

Dans le cas a est une variable globale, vous pouvez également utiliser var a = window.a; comme woz suggested - mais comme ayant des variables globales est généralement mauvaise idée mieux rester avec les paramètres.

+0

Alors, comment Je fais en sorte que ma variable locale et la variable globale sont égales au début de la portée de la fonction locale? Dois-je utiliser une variable temporaire? – Neal

+1

Voir ma modification. Vous ne pouvez pas utiliser une variable temporaire car peu importe ce que vous faites, dès qu'il y a 'var a' dans votre fonction, le' a' externe n'est plus accessible. – ThiefMaster

+0

Ooohh J'ai oublié les paramètres :-P Duuuuh. '+ 1' – Neal

0

il y a un levage variable javascript, de sorte que votre code pendant exécution ressemble à ceci:

(function() { 
    var a; 
    a = a; //want to make local a = global a 
    ++a; 
    console.log("fn",a); 
})(); 

donc tout d'abord vous avez variable locale a comme définie et vous attribuez non défini à la variable une

5

Le a variable à l'intérieur de votre expression de fonction ombres la variable a déclarée sur la portée externe.

Il devient NaN, puisque dans la mission:

var a = a; 

Le côté droit a il fait référence en fait à la a dans la portée locale.

Les déclarations de variables sont effectuées avant que la fonction commence réellement à être exécutée, ce qui est communément appelé «levage».

Puisqu'il est la même variable, elle détient la valeur undefined, et lorsque vous essayez d'ajouter un nombre à cette valeur, il devient NaN:

console.log(undefined + 0); 
2

En JavaScript, le execution context (courant qui inclut des choses comme variable scope) est établi avant votre code commence à s'exécuter. Ce que cela signifie pour vous, c'est que vos noms de variables locales sont alloués en premier.En raison de levage, étiquettes de var instructions partout dans la fonction sont initialisées à undefined dans le contexte d'exécution en cours. (Les instructions de fonction sont également initialisées dans cette étape.)

Ensuite, votre code commence réellement à s'exécuter. Le libellé a est déjà réservé dans le contexte d'exécution en cours. Par conséquent, var a = a; affecte simplement le a local (non défini) à lui-même.

var a = window.a fonctionne parce que vous contournez le problème de portée en accédant directement à la portée globale. Cependant, cela ne fonctionne pas dans les environnements non-navigateur (comme Node), car il n'y a pas window; l'objet global dans le nœud est global.