2015-03-25 13 views
14

Chỉ cần ra khỏi tò mò ..Mặc nhiên toàn cầu "mục" biến - sự khác biệt giữa Internet Explorer và FireFox

Tôi có điều này JS mã:

var someExternalArray = [{id: 1, name: 'a'}, {id: 2, name: 'b'}, {id: 3, name: 'c'}]; 
var newArray = [] 

//var item; 
for (var i = 0; i < someExternalArray.length; i++){ 
    item = new Object(); 
    item.id = someExternalArray[i].id; 
    item.name = someExternalArray[i].name; 
    newArray.push(item); 
} 

alert('0:' + newArray[0].name + ',1:' + newArray[1].name + ',2:' + newArray[2].name); 

Thông báo các nhận xét var item mà rời khỏi vòng lặp với ngầm tuyên bố item biến.

  • Nếu tôi chạy mã này trên FireFox, kết quả của báo là: 0:a,1:b,2:c

  • Nếu tôi chạy cùng mã trong trình duyệt Internet Explorer, kết quả là: 0:c,1:c,2:c

Đây là jsfiddle: https://jsfiddle.net/fvu9gb26/

Tất nhiên, khi tôi bỏ ghi chú var item nó hoạt động theo cùng một cách trong mọi trình duyệt.

Có ai biết tại sao sự khác biệt này xảy ra không? Cảm ơn bạn.

Trả lời

7

Về cơ bản, đó là do đối tượng window của Internet Explorer hiển thị phương thức item() mà tập lệnh của bạn không thể ghi đè.

Trong dòng:

item = new Object(); 

item không được khai báo trong phạm vi địa phương, vì vậy nó được xem như là một tài sản của đối tượng toàn cầu (window.item). Trên Firefox, window không hiển thị thành viên có tên item, vì vậy một thành viên mới được giới thiệu và kết quả của new Object() được gán cho nó.

Mặt khác, Internet Explorer hiển thị phương pháp gốc có tên window.item(). Thành viên đó không thể ghi, do đó nhiệm vụ không thể diễn ra - nó bị bỏ qua một cách thầm lặng. Nói cách khác, item = new Object() không có tác dụng gì cả (tốt, nó tạo ra một đối tượng nhưng không thể gán nó sau đó).

Các bài tập tiếp theo tới idname sẽ kết thúc tạo thành viên mới của phương thức item(). Đây luôn là cùng một thành viên của cùng một phương pháp, vì vậy giá trị của chúng được ghi đè lên mỗi lần lặp vòng lặp. Ngoài ra, cùng một đối tượng (phương thức item()) được đẩy tới mảng trên mỗi lần lặp.

Do đó, mảng kết thúc chứa ba lần so với cùng một đối tượng, và các giá trị của idname thành viên của nó là những giá trị cuối cùng được giao (trong phiên trước), tương ứng 3'c'.

+0

Cảm ơn bạn. Điều này thực sự là một sự trùng hợp mà chúng ta quên khai báo 'var item' vì chúng ta luôn khai báo biến trong dự án của mình và không bao giờ dựa vào khai báo ngầm. Và thứ hai, biến này có cùng tên với một số phương thức gốc trên 'đối tượng cửa sổ' chỉ tồn tại trong IE..wow :) –

5

Đây là điều khó khăn. Đối với một số lý do không rõ ràng, Internet Explorer có một phương thức gốc được gọi là item trong ngữ cảnh toàn cầu window (nếu ai đó biết lý do, bạn được quyền chia sẻ: Tôi không thể tìm thấy nó trong tài liệu). Vì vậy, khi bạn sử dụng số nhận dạng item mà không khai báo biến, nó đề cập đến phương pháp này.

Hướng dẫn đầu tiên trong vòng lặp (item = new Object();) không làm gì vì window.item là thuộc tính chỉ đọc. Vì vậy, sau lệnh này, window.item vẫn là hàm gốc.

Hướng dẫn tiếp theo (các thiết lập idname) hoạt động, bởi vì trong khi thuộc tính window.item là chỉ đọc, đối tượng Function mà chỉ trỏ có thể được sửa đổi.

Sau vòng lặp, bạn đã thêm cùng một đối tượng Function ba lần và chỉ tính số lần lặp lại cuối cùng vì bạn ghi đè các thuộc tính idname mọi lúc.

+1

LMAO !! Tôi tình cờ gặp ở đây vì tôi đang sử dụng bối cảnh vật phẩm cũng như trong vòng lặp của tôi. Tôi đã được looping thông qua các mục từ hàng tồn kho của tôi từ JSON và giao mục biến cho nó ... những thứ kỳ lạ microsoft! Haha. Sửa lỗi đơn giản cho tôi chỉ là thêm var trước mục. –

Các vấn đề liên quan