2010-09-16 2 views
24
alert(myVar1); 
return false; 
var myVar1; 

Le code ci-dessus renvoie une erreur dans IE, FF et Opera indiquant que l'instruction return doit entrer dans la fonction. Mais cela fonctionne (montre undefined) dans Safari et Chrome.Levage de variable

Le code ci-dessus a été écrit dans un contexte mondial. En dehors de toutes les fonctions.

Une raison?

+10

Je suis effrayée, confuse et légèrement intriguée ... qu'est-ce que vous essayez de complice? –

+2

@Hahsen, j'essaie juste de comprendre les divers gotchas de navigateur et de javascript disponibles. C'est une opération de levage variable et j'essaie de comprendre son comportement dans une portée globale avec une déclaration de retour. Bien que le retour ne soit pas autorisé quand vous n'êtes pas dans la définition de fonction mais que le code fonctionne en chrome et safari.J'essaie de trouver la raison – alter

+0

Il pourrait être plus facile de le comprendre comme variable et déclaration * pré-traitement *. Les déclarations ne sont pas déplacées (ou "hissées en haut"), elles sont traitées avant que le code ne soit exécuté. Lire ECMA-262 §10.3 sur ce qui se passe lors de la saisie d'un contexte d'exécution, il est raisonnablement facile à comprendre. – RobG

Répondre

23

Variables JAVASCRIPT sont déplacés vers le haut du scénario et puis exécutez. Ainsi, lorsque vous exécutez fera

var myVar1; 
alert(myVar1); 
return false; 

C'est parce que le javascript ne marche pas vraiment avoir un vrai sens de la portée lexicale. C'est pourquoi il est considéré comme la meilleure pratique d'avoir toutes vos variables déclarées en haut de la zone, elles seront utilisées pour empêcher le levage causant un problème. JSLint va se plaindre à ce sujet.

Ceci est un bon article qui explique http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

Le retour est invalide. Si vous voulez faire un exemple vrai de levage (prises à partir du lien ci-dessus) ne

var foo = 1; 
function bar() { 
    if (!foo) { 
     var foo = 10; 
    } 
    alert(foo); 
} 
bar(); 

Cette alertera 10

EDIT APRÈS UN COMMENTAIRE

Ci-dessous est ma compréhension et je l'ai lu quelque part, mais ne peut pas trouver toutes les sources que je lis donc je suis ouvert à la correction.

Cette alertes grâce aux différences dans le JavaScript JIT. TraceMonkey (http://ejohn.org/blog/tracemonkey/) Je crois qu'il va prendre le JavaScript et faire une analyse statique rapide, puis faire JIT, puis essayez de l'exécuter. Si cela échoue, il est évident que rien ne fonctionne. V8 ne fait pas l'analyse statique et se déplace vers le JIT puis exécute donc quelque chose. C'est plus proche de python. Si vous exécutez le script dans la console du développeur (ctrl + shift + j dans Windows) dans Chrome, une erreur sera générée, mais elle sera également exécutée pour vous donner l'alerte.

+1

@Automater Tester, votre code a parfaitement raison et c'est un très bel exemple de levage en javascript. Mais ce que je veux savoir, c'est pourquoi le retour n'a pas jeté d'erreur dans le chrome et le safari – alter

+0

@alter J'ai ajouté plus d'infos pour vous. – AutomatedTester

+3

"Dans javaScript, les variables sont déplacées en haut du script, puis exécutées." En fait, les variables * noms * (et non les affectations/définitions) sont "hissées" en haut de la portée contenante (celle qui est la plus proche, "si" et "al" ne * crée * pas de "portée" dans ce sens). – strager

3

Ce code fait peu de sens:

  • Le var myVar1 ne sera jamais couru.
  • Le return false; ne reviendra pas une chose puisque vous n'êtes pas dans une fonction

Opera, IE et FF ont raison de lancer une erreur car ce code est vraiment pas valide puisque vous n'êtes pas en mesure de revenir sauf si vous êtes dans une fonction. Si cela fonctionne dans Safari et Chrome, cela doit être dû au fait que le moteur JavaScript qu'ils utilisent est prêt à gérer du code buggé. Ma conjecture serait qu'ils voient le "return" et laisser tomber ou le remplacer par une sorte de break.

Plus d'informations sur les fonctions: http://www.w3schools.com/js/js_functions.asp

+0

Erreurs de chrome pour moi lorsque j'utilise une instruction * return * en dehors d'une fonction. –

+3

var myVar1 sera toujours exécuté grâce à la levée – AutomatedTester

+0

indépendamment du fait que la déclaration de retour n'est pas autorisée sans une fonction, le hoising aurait dû se produire ici et j'aurais dû avoir une alerte disant indéfini. Je ne vois pas cela se produire quand j'ai une déclaration de retour. – alter

10

Section 12.9 (page 75) de ECMA-262 Edition 3 états:

An ECMAScript program is considered syntactically incorrect if it contains a return statement that is not within a FunctionBody.

C'est un return en dehors d'une fonction est une erreur de syntaxe . Si une erreur de syntaxe se produit, aucun code n'est exécuté. Pensez à votre exemple comme si vous aviez écrit:

alert(myVar1); 
return false; 
syntax error)))))))))))))))))); 

En outre, l'article 16 (page 157) indique:

An implementation may treat any instance of the following kinds of runtime errors as a syntax error and therefore report it early:

  • Improper uses of return, break, and continue.

moteur de Firefox et. Al. (Ceux JavaScript implémentations qui permettent return dans la portée globale) peut être conformes, en supposant la clause suivante (dans la même section) permet la définition de la mise en œuvre de return dans la portée globale:

An implementation shall report all errors as specified, except for the following:

  • An implementation may provide additional types, values, objects, properties, and functions beyond those described in this specification. This may cause constructs (such as looking up a variable in the global scope) to have implementation-defined behaviour instead of throwing an error (such as ReferenceError).
0

Il est JavaScript hissage chose, simplement en d'autres termes, nous essayons imprimer la valeur de la variable, qui ne tient aucune valeur

Javascript va rendre le code ci-dessus: -

var myVar1 
 
alert (myVar1) 
 
return false

Pour clarifier plus je refered le lien javascript levage: http://www.ufthelp.com/2014/11/JavaScript-Hoisting.html

11

Parfois levage est expliqué d'une manière qui peut donner une fausse impression, à savoir les variables et les fonctions sont hissés par le moteur JavaScript comme si elles étaient déplacés physiquement sur le dessus, ce qui est en fait juste, comme le montre le code ci-dessous:

console.log(a); 
var a = 'Hello World!'; 

Ce que nous voyons sur la console est undefined, pas 'Hello World', donc nous avons eu la Beha Vior du code ci-dessous

var a; 
console.log(a); 
a = 'Hello World!'; 

pas le comportement de

var a = 'Hello World!'; 
console.log(a); 

que vous pouvez avoir l'impression de la déclaration des variables et des fonctions déplacé à la déclaration haut.

Mais JavaScript ne déplace pas votre code n'importe où. Vous devez comprendre le contexte d'exécution en JavaScript. Il a deux phases de phase de création et de phase d'exécution. En phase de création, de l'espace mémoire est créé pour ces variables et fonctions, et les gens semblent confondre cette étape avec le levage. JavaScript ne déplace pas votre code, JavaScript crée un espace mémoire pour toutes vos variables et fonctions, les fonctions peuvent être placées en mémoire mais dans le cas de variables, les affectations sont traitées en phase d'exécution du contexte d'exécution. Donc quand vous faites var a = 'Hello World!', le moteur JavaScript connaît la valeur de a quand il commence à l'exécuter en phase d'exécution du contexte d'exécution, donc il place un espace réservé indéfini, et toutes les variables sont initialement définies à indéfini en JavaScript. Il n'est donc pas bon de compter sur le levage et voir indéfini. Il est donc toujours bon de déclarer des variables et des fonctions au-dessus de votre code.