2009-07-02 32 views
60

Tôi không thể tìm thấy bất kỳ thông tin nào về vấn đề này; tại sao mã sau không hoạt động trong IE?Xóa thuộc tính cửa sổ trong IE

window.x = 45; 
delete window.x; 
// or delete window['x']; 

IE báo cáo lỗi "đối tượng không hỗ trợ hành động này". Liệu nó có liên quan đến việc lặp lại các thuộc tính cửa sổ trong vấn đề IE không?

+25

Và chỉ để rõ ràng, bởi vì nó không giống như bất cứ ai thực sự nói điều này trong bất kỳ câu trả lời: Đây là một * lỗi * trong Internet Explorer. Không có gì trong đặc tả năm 1999 (phiên bản thứ 3) cho phép ném một ngoại lệ từ 'delete', ngay cả khi thuộc tính không tồn tại hoặc không thể truy xuất được (trong đó' window.x' của bạn sẽ không nằm trong bất kỳ trường hợp nào), và Thông số phiên bản 5 mới chỉ cho phép ngoại lệ được ném từ 'xóa' ở chế độ nghiêm ngặt mới. Không có gì đặc biệt về 'cửa sổ' trong vấn đề này. Chưa hết, công cụ JScript trong IE8 * vẫn * thể hiện lỗi này, vào năm 2010. * thở dài * –

+2

[Bài viết liên quan tốt] (http://perfectionkills.com/understanding-delete/). – alex

+0

T.J. Crowder, cửa sổ không phải là một đối tượng, nó là một accessor đến không gian tên gốc. Nó không có thuộc tính như vậy, vì vậy khi bạn chạy xóa trên nó, chẳng hạn như trong trường hợp này, nó không có nghĩa vụ phải thực sự loại bỏ chúng vì bất kỳ lý do gì. Thiết lập không xác định trên tên của đối tượng là tốt để làm bởi vì gc sẽ đi qua và loại bỏ các đối tượng unreferenced. Hy vọng điều này sẽ giúp hiểu vấn đề thực tế ở đây và tại sao điều này không phải là một lỗi vì nó là một sự lựa chọn thực hiện nghèo cho ngôn ngữ đang dần cập nhật để hiện đại hóa –

Trả lời

31

tôi sẽ làm điều đó theo cách này:

window[x] = undefined; 
    try{ 
     delete window[x]; 
    }catch(e){} 
+0

cảm ơn, đó là những gì tôi đã làm cuối cùng. Nó ném một ngoại lệ trong IE, nhưng nó bị bắt và không có thiệt hại nào được thực hiện. –

+0

Giải thích chi tiết nhất về xóa tôi đã thấy ở đây, đây là phần IE. (Trong trường hợp ai đó đến đây với một vấn đề phức tạp hơn trong tương lai) http://perfectionkills.com/understanding-delete/#ie_bugs –

2

Điều này có hữu ích không?

window.x = 45; 
alert(window.x); 
window.x = null; 

Tôi đã thử điều này trong IE và window.x đã có giá trị, chứng minh rằng nó có thể được đặt. Đặt giá trị thành null là cách tốt nhất để xóa nó.

+0

Thật không may điều này không loại bỏ biến từ bộ nhớ, nó chỉ cung cấp cho nó một giá trị null, nhưng đây là lựa chọn duy nhất theo như tôi có thể nói. –

+1

Cảm ơn. Tôi đã đi một bước xa hơn và sử dụng window.x = undefined. Điều này vẫn không phải là những gì tôi muốn, nhưng nó sẽ làm.Thật kỳ lạ khi tôi không tìm thấy bất kỳ thông tin hữu ích nào trên web về điều này. –

48

Gasper đã viết nhận xét với các giải pháp ông kết thúc, nhưng tôi nghĩ rằng nó đáng để gọi ra như một câu trả lời thực tế:

try 
{ 
    delete window.x; 
} 
catch(e) 
{ 
    window["x"] = undefined; 
} 

Thú vị vấn đề , Tôi vừa đập đầu vào tối nay. Ngoại lệ được ném trên IE nhưng không phải là Firefox. Tôi sẽ nghi ngờ cách này giải phóng bộ nhớ, vì vậy hãy sử dụng một cách tiết kiệm.

Đã hỏi, tại sao không chỉ định không xác định? Nó quan trọng nếu bạn muốn liệt kê các khóa sau này (mặc dù nếu bạn đang dựa vào cách giải quyết, việc liệt kê chính vẫn sẽ không làm những gì bạn muốn ...). Nhưng dù sao đi nữa, để làm nổi bật sự khác biệt giữa xóa và chỉ cần gán không xác định (http://jsfiddle.net/fschwiet/T4akL/):

var deleted = { 
    a: 1 
}; 

var cleared = { 
    a: 1 
}; 

delete deleted["a"]; 
cleared["a"] = undefined; 

for(var key in deleted) { 
    console.log("deleted has key", key); 
} 

for(var key in cleared) { 
    console.log("cleared has key", key); 
} 

console.log("deleted has a?", deleted.hasOwnProperty('a')); 
console.log("cleared has a?", cleared.hasOwnProperty('a')); 

sản xuất đầu ra:

cleared has key a 
deleted has a? false 
cleared has a? true 
+4

Một đồng nghiệp đã hỏi một người tốt khi tôi chỉ cho họ giải pháp này: tại sao không bỏ qua người đàn ông trung gian và thay thế cuộc gọi xóa bằng bài tập chưa xác định? –

+0

Câu hỏi hay, tôi mất một năm để chạy vào trường hợp có sự khác biệt quan trọng. –

1

tôi thực hiện giải pháp này khi giao dịch với bộ nhớ đệm dữ liệu của riêng tôi - các dữ liệu wasn' t nhiều tần số của bộ nhớ cache là như vậy mà rò rỉ bộ nhớ có thể đã trở thành một vấn đề. Đó là tốn kém, nhưng định kỳ remapping đối tượng là cách dễ nhất cho tôi để chắc chắn rằng nó đã không nhận được ra khỏi bàn tay.

obj = {a: 1, b: 2, c: 3}; 
var max; 

function unset(obj, key) { 
    try { 
     delete obj[key]; 
    } catch (e) { 
     obj[key] = undefined; 
    } 

    max++; 

    if(max > 200) { 
     var keys = Object.keys(obj); 
     var len = keys.length; 
     var n_obj = {}; 
     for(var i = 0; i < len; i++) { 
      if(obj.hasOwnProperty(keys[i]) && obj[keys[i]] !== undefined) { 
       n_obj[keys[i]] = obj[keys[i]]; 
      } 
     } 
     return n_obj; 
    } 
    return obj; 
} 

obj; //{a: 1, b: 2, c: 3} 
obj = unset(obj, "b"); //{a: 1, b: undefined, c: 3} OR {a: 1, c: 3} 
//and then eventually we'll garbage collect and... 
obj = unset(obj, "b"); //{a: 1, c: 3} 

Hy vọng điều đó hữu ích đối với một số người!

+2

'Object.keys()' sẽ không hoạt động trong <= IE8 (là những cái gây rắc rối với 'xóa' ở vị trí đầu tiên). Ngoài ra, bạn có thể có nghĩa là 'obj [key] = undefined' bên trong khối catch. ;] – WynandB

+0

đó sẽ là nó! đã sửa đổi. – Mikebert4

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