9

(tworząc oddzielny pytanie po komentarzach na ten temat: Javascript redeclared global variable overrides old value)Redeclared javascript zmienna globalna zastępuje stary wartość w IE

tworzę globalnie scoped zmienną używając notacji kwadratowej uchwytu i przypisując mu wartość wewnątrz pliku zewnętrznego js .

W innym pliku js deklaruję var o tej samej nazwie, co właśnie utworzony powyżej. Uwaga Nie przypisuję wartości. Ponieważ jest to ponowna deklaracja tej samej zmiennej stara wartość nie powinna być nadpisane jak opisano tutaj: http://www.w3schools.com/js/js_variables.asp

utworzyć 2 pliki javascript o następującej treści: 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 

Dołącz te 2 pliki do pliku html

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

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

</body> 
</html> 

Otwarcie tej strony w Firefoksie i starych alertach Chrome "oczekiwane zachowanie". Jednak w IE 8 strona będzie automatycznie powiadamiać "nowe"

Wszelkie pomysły na to, dlaczego tak się dzieje w IE?

+0

Co się stanie, jeśli wstawisz cały kod w pliku HTML? Daje ten sam wynik (stary) dla mnie w Firefox 3.5.8, Chrome 5.0.342.7 i Konqueror 4.3.5. Przydatne będą wyniki dla innych przeglądarek. –

+0

Jeśli umieścisz cały kod w jednym pliku, nastąpi jego wciągnięcie, a problem prawdopodobnie nie będzie obecny. –

+0

Tak, jeśli umieścisz cały kod w jednym miejscu, alert wyświetli "stary" we wszystkich przeglądarkach. –

Odpowiedz

4

Jeśli spodziewasz się, że y będzie globalny, możesz po prostu całkowicie zrzucić linię var y w drugim pliku.

Powodem tego jest to, że ponieważ chcesz, aby y była globalna, traktuj ją jak globalną i już zadeklarowaną. Efekt uboczny JavaScriptu polegający na tym, że zmienne globalne są zadeklarowane bez prefiksu var, grają na twoją korzyść w tej sytuacji. Testowane w IE8, działa to dobrze.

Edycja: Jeśli chodzi o to, dlaczego tak się dzieje, przypuszczam, że jest to po prostu błąd w połączeniu globalnych operacji IE w plikach i podnoszeniu deklaracji. Naprawdę jednak powinieneś zadeklarować dowolną zmienną, ale przede wszystkim globalną, w jednym miejscu. Twój problem można uniknąć, stosując się do tej reguły.

+1

Dzięki za tę sugestię. Ma sens. Chociaż nadal byłoby interesujące wiedzieć, dlaczego to nie działa poprawnie w IE. –

+1

O dziwo, wydaje się, że IE może mieć błąd w implementacji JavaScript. –

+0

Tak, najlepiej chcielibyśmy zadeklarować globalny tylko w jednym miejscu. Moim przypadkiem użycia było to, że miałem wiele plików js, z których każda deklarowała klasę z pustymi przestrzeniami, używając tego wzoru: Script1: Script1: Skrypt (! A) a = {}; a.b = function() {....}; Script2 if (! A) a = {}; a.c = function() {....}; Teraz działa dobrze, dopóki pierwszy skrypt nie użyje window.a lub window ['a'] do zadeklarowania a następnie IE breaks. Ponieważ wiele stron może wybrać pliki do uwzględnienia, każdy z nich musi sprawdzić, czy istnieje. –

1

Dzieje się tak w IE, ponieważ linia ponownej deklaracji ustawia wartość y na niezdefiniowaną. Następnie testowanie linii, jeśli y nie jest ustawione, przechodzi, a y zmienia się na "nowe".

Zmień drugi skrypt:

//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

Dobrze, rozumiem to. Ale gdybyś scalił zawartość 2 plików w jednym miejscu, nie byłbyś już niezdefiniowany i redeclaracja nie ustawiłaby y na niezdefiniowaną. W wyniku tego alert wyświetli "stary" –

+0

W IE wszystkie deklaracje są wykonywane przed innymi częściami kodu. W drugim przypadku, jeśli zrobisz pierwszy alert liniowy (okno ["y"]), zobaczysz, że wartość jest niezdefiniowana. Jeśli skomentujesz linię redeclaration, zobaczysz oczekiwane "stare". – Jonathan

+0

W rzeczywistości dzieje się tak we wszystkich przeglądarkach i nazywa się * hoisting *; wydaje się jednak, że IE robi to źle w tym scenariuszu i powoduje nadpisanie. –

9

uproszczony przypadek testowy:

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

I tak, to absolutnie jest to błąd w silniku IE JScript.

Dlaczego tak się dzieje? Dlaczego IE robi jakieś szalone rzeczy, które robi? Zirytuj hałas, chodź, staraj się tego uniknąć ...

+0

W porządku, w końcu nie jestem szalony. –

+2

Jeśli zawęziłeś to do "coś złego z tobą" i "coś nie tak z IE", idź z IE za każdym razem ... – bobince