9

(tạo ra một câu hỏi riêng biệt sau khi bình luận về điều này: Javascript redeclared global variable overrides old value)redeclared javascript toàn cầu đè biến giá trị cũ trong IE

tôi đang tạo ra một scoped toàn cầu biến bằng cách sử dụng ký hiệu khung vuông và gán cho nó một giá trị bên trong tập tin một bên ngoài js .

Trong tệp js khác, tôi khai báo một biến có cùng tên với tên tôi vừa tạo ở trên. Lưu ý Tôi không chỉ định giá trị. Do đây là một khai báo lại của biến cùng giá trị cũ không nên overriden như đã mô tả ở đây: http://www.w3schools.com/js/js_variables.asp

Tạo 2 file javascript với nội dung sau: 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 

Bao gồm 2 tệp này trong tệp html của bạn

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

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

</body> 
</html> 

Mở trang này trong Firefox và cảnh báo Chrome 'cũ' là hành vi mong đợi. Tuy nhiên trong IE 8 trang sẽ thực sự cảnh báo 'mới'

Bất kỳ ý tưởng nào về lý do tại sao điều này xảy ra trên IE?

+0

Điều gì sẽ xảy ra nếu bạn đặt tất cả mã nội tuyến trong tệp HTML? Nó mang lại kết quả tương tự (cũ) cho tôi trong Firefox 3.5.8, Chrome 5.0.342.7 và Konqueror 4.3.5. Kết quả cho các trình duyệt khác sẽ hữu ích. –

+0

Nếu bạn đặt tất cả các mã trong một tập tin, cẩu sẽ xảy ra và vấn đề có thể sẽ không có mặt. –

+0

Có nếu bạn đặt tất cả mã trong một cảnh báo địa điểm duy nhất hiển thị 'cũ' trên tất cả các trình duyệt –

Trả lời

4

Nếu bạn mong đợi y là toàn cầu, bạn có thể chỉ cần thả toàn bộ dòng var y trong tệp thứ hai của mình.

Lý do đằng sau điều này là vì bạn muốn y là toàn cầu, hãy xử lý nó như toàn cầu và đã được khai báo. Tác dụng phụ của JavaScript khi tạo biến toàn cầu khi được khai báo mà không cần tiền tố var có lợi cho bạn trong trường hợp này. Thử nghiệm trong IE8, điều này hoạt động tốt.

Chỉnh sửa: Về lý do tại sao điều này xảy ra, tôi sẽ viết lên nó chỉ là một lỗi trong sự kết hợp xử lý các hình cầu của IE trên các tệp và bản khai báo. Thực sự, tuy nhiên, bạn chỉ nên khai báo bất kỳ biến nào, nhưng đặc biệt là một biến toàn cầu, ở một nơi. Vấn đề của bạn có thể tránh được bằng cách làm theo quy tắc này.

+1

Cảm ơn đề xuất đó. Có ý nghĩa. Mặc dù nó vẫn sẽ là thú vị để biết lý do tại sao điều này không hoạt động chính xác trong IE. –

+1

Đáng ngạc nhiên, có vẻ như IE có thể có lỗi trong việc triển khai JavaScript của nó. –

+0

Có, lý tưởng là chúng tôi muốn tuyên bố toàn cầu chỉ ở một nơi. Trường hợp sử dụng của tôi là tôi có nhiều tệp js, mỗi tệp trong số đó đã khai báo một lớp không có tên bằng cách sử dụng mẫu này: Script1: if (! A) a = {}; a.b = function() {....}; Script2 nếu (! A) a = {}; a.c = function() {....}; Hiện tại, công cụ này hoạt động tốt cho đến khi tập lệnh đầu tiên sử dụng window.a hoặc cửa sổ ['a'] để khai báo và sau đó tắt IE. Vì nhiều trang có thể chọn tệp để bao gồm mỗi tệp phải kiểm tra xem có tồn tại hay không. –

1

Điều này đang xảy ra trong IE vì dòng khai báo lại đang đặt y thành không xác định. Sau đó, kiểm tra đường dây nếu y không được đặt và y thay đổi thành "mới".

Thay đổi kịch bản thứ hai để:

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

Tôi hiểu điều đó. Nhưng nếu bạn đã hợp nhất nội dung của 2 tệp ở một nơi y sẽ không còn được xác định và việc xác nhận lại sẽ không đặt y thành không xác định. Kết quả là cảnh báo sẽ hiển thị 'cũ' –

+0

Trong IE, tất cả các khai báo được thực thi trước các phần khác của mã. Trong phần thứ hai, nếu bạn tạo cảnh báo dòng đầu tiên (cửa sổ ['y']), bạn sẽ thấy rằng giá trị không được xác định. Nếu bạn nhận xét ra dòng redeclaration bạn sẽ thấy dự kiến ​​'cũ' xuất hiện. – Jonathan

+0

Thực ra, điều này xảy ra ở tất cả các trình duyệt và được gọi là * cẩu *; Tuy nhiên, có vẻ như IE đang làm sai trong kịch bản này và gây ra một ghi đè. –

9

Giản kiểm tra trường hợp:

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

Và vâng, đây hoàn toàn là một lỗi trong công cụ JScript của IE.

Tại sao điều đó xảy ra? Tại sao IE làm bất kỳ điều điên rồ nào? Hãy tạo ra tiếng động khó chịu, tiếp tục, cố gắng tránh làm điều này ...

+0

Được rồi, cuối cùng tôi không điên. –

+2

Nếu bạn đã thu hẹp nó xuống để "một cái gì đó sai trái với bạn" và "một cái gì đó sai với IE", đi với IE mỗi lần ... – bobince