9

(créer une autre question après les commentaires sur ce point: Javascript redeclared global variable overrides old value)redéclarée javascript overrides variable globale ancienne valeur dans IE

Je crée une variable SCOPED globalement en utilisant la notation de support carré et en lui attribuant une valeur à l'intérieur d'un fichier externe .

Dans un autre fichier js, je déclare un var avec le même nom que celui que je viens de créer ci-dessus. Remarque Je n'attribue pas de valeur. Comme il s'agit d'une redéclaration de la même variable la valeur ancienne ne doit pas être surchargée comme décrit ici: http://www.w3schools.com/js/js_variables.asp

Créer 2 fichiers javascript avec le contenu suivant: Script1

//create global variable with square bracket notation 
window['y'] = 'old'; 

Script2

//redeclaration of the same variable 
var y; 

if (!y) y = 'new'; 

alert(y); //shows New instead of Old in IE 

Inclut ces 2 fichiers dans votre fichier html

<html> 
<head></head> 
<body> 

    <script type="text/javascript" src="my.js"></script> 
    <script type="text/javascript" src="my2.js"></script> 

</body> 
</html> 

L'ouverture de cette page dans Firefox et les alertes Chrome "vieux" qui est le comportement attendu. Cependant, dans IE 8, la page va effectivement alerter «nouveau»

Des idées sur pourquoi cela se produit sur IE?

+0

Que se passe-t-il si vous mettez tout le code en ligne dans le fichier HTML? Il me donne le même résultat (ancien) pour Firefox 3.5.8, Chrome 5.0.342.7 et Konqueror 4.3.5. Les résultats pour les autres navigateurs seraient utiles. –

+0

Si vous mettez tout le code dans un fichier, le levage se produira et le problème ne sera probablement pas présent. –

+0

Oui, si vous mettez tout le code dans un seul endroit l'alerte montre «vieux» sur tous les navigateurs –

Répondre

4

Si vous pensez que y est global, vous pouvez simplement supprimer la ligne var y dans votre deuxième fichier.

Le raisonnement derrière cela est que puisque vous voulez y être global de toute façon, il suffit de le traiter comme un global et déjà déclaré. L'effet secondaire de JavaScript de rendre les variables globales lorsqu'elles sont déclarées sans le préfixe var joue en votre faveur dans cette situation. Testé dans IE8, cela fonctionne très bien. Editer: Pour ce qui est de savoir pourquoi cela se produit, je dirais que c'est juste un bug dans la combinaison de la gestion des globals par IE et de la levée des déclarations. Vraiment, cependant, vous devriez seulement déclarer n'importe quelle variable, mais surtout globale, dans un endroit. Votre problème peut être évité en suivant cette règle empirique.

+1

Merci pour cette suggestion. Logique. Bien qu'il serait toujours intéressant de savoir pourquoi cela ne se comporte pas correctement dans IE. –

+1

Étonnamment, il semble que IE peut avoir un bug dans son implémentation JavaScript. –

+0

Oui, idéalement, nous voulons déclarer un global dans un seul endroit. Mon cas d'utilisation était que j'avais plusieurs fichiers js dont chacun déclarait une classe namespaced en utilisant ce modèle: Script1: if (! A) a = {}; a.b = fonction() {....}; Script2 si (! A) a = {}; a.c = fonction() {....}; Maintenant, cela fonctionne bien jusqu'à ce que le premier script utilise window.a ou la fenêtre ['a'] pour déclarer un et puis les ruptures IE. Étant donné que plusieurs pages peuvent choisir les fichiers à inclure, chacun d'eux doit vérifier si un existe. –

1

Cela se produit dans IE car la ligne de re-déclaration définit y sur indéfini. Ensuite, le test de ligne si y n'est pas défini passe et y passe à "nouveau".

Modifier le second script:

//redeclaration of the same variable 
var y; 

alert(y); // is undefined in IE 

if (!y) y = 'new'; 

alert(y); //shows New instead of Old in IE 
+0

Je comprends cela. Mais si vous fusionniez le contenu des deux fichiers en un seul endroit, vous ne seriez plus indéfini et la redéclaration ne définirait pas y à indéfini. Par conséquent, l'alerte affichera «ancien» –

+0

Dans IE, toutes les déclarations sont exécutées avant les autres parties du code. Dans le deuxième include si vous faites l'alerte de première ligne (window ['y']) vous verrez que la valeur n'est pas définie. Si vous commentez la ligne de redéclaration, vous verrez apparaître l'ancien. – Jonathan

+0

En fait, cela se produit dans tous les navigateurs et s'appelle * levage *; Cependant, il semble que IE le fait mal dans ce scénario et provoquant un écrasement. –

9

cas de test simplifié:

<script> 
    window.foo= 1; 
</script> 
<script> 
    var foo; 
    alert(foo); 
</script> 

Et oui, ce absolument est un bug dans le moteur JScript IE.

Pourquoi cela se produit-il? Pourquoi IE fait-il des choses folles? Faire un bruit irrité, passer à autre chose, essayer d'éviter cela ...

+0

Bon, enfin je ne suis pas fou. –

+2

Si vous avez réduit à "quelque chose ne va pas avec vous" et "quelque chose ne va pas avec IE", allez avec IE à chaque fois ... – bobince