在IE中删除窗口属性


68

我找不到有关此问题的任何信息;为什么下面的代码在IE中不起作用?

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

IE报告“对象不支持此操作”错误。与在IE问题中遍历窗口属性有什么关系吗?


29
还要明确一点,因为在任何答案中似乎都没有人真正说过:这是Internet Explorer中的错误。在1999年(第3版)规范中,没有任何内容允许从引发异常delete,即使该属性不存在或不可删除(window.x无论如何也不应该),而新的第5版规范仅允许引发异常来自delete新的严格模式。window在这方面没有什么特别的。但是,IE8中的JScript引擎在2010
TJ Crowder


TJ Crowder,窗口不是对象,它是根名称空间的访问器。它没有这样的属性,因此,当您在其上运行delete时,例如在这种情况下,由于任何原因,它实际上都没有义务将其删除。在对象名称上设置undefined很好,因为gc会通过并消除未引用的对象。希望这有助于理解这里的实际问题,以及为什么这不是一个错误,因为对于缓慢更新以实现现代化的语言来说,这是一个糟糕的实现选择
Jeffrey Gilbert

Answers:



49

Gasper对他完成的解决方案发表了评论,但我认为值得一提的是实际答案:

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

有趣的是,我今晚正好撞上它。IE上抛出了异常,但Firefox上没有。我怀疑这种解决方法会泄漏内存,因此请谨慎使用。

有人问,为什么不分配未定义?如果您以后要枚举键,这很重要(尽管如果您依靠变通办法,键枚举仍然无法满足您的要求...)。但是无论如何,要突出显示删除和简单地分配未定义(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'));

产生输出:

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

4
当我向他们展示此解决方案时,一位同事问一个好人:为什么不跳过中间人,并用未定义的分配替换delete调用?
塞斯·巴丁

很好的问题,我花了一年的时间才发现差异很重要的情况。
Frank Schwieterman

2

这有帮助吗?

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

我在IE中尝试过,window.x确实有一个值,证明可以设置。将值设置为null是清除它的最佳选择。


不幸的是,这并没有从内存中删除该变量,它只是为它提供了一个空值,但是据我所知,这是唯一的选择。
安迪E

1
谢谢。我走了一步,并使用window.x = undefined。这仍然不是我想要的,但是会的。奇怪的是,我没有在网络上找到任何有用的信息。
gasper_k

1

在处理我自己的数据时,我实现了此解决方案-数据的频率与缓存的频率无关,因此内存泄漏可能已成为问题。这很昂贵,但是定期重新映射对象是我确定它不会失控的最简单方法。

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}   

希望这对某些人有用!


2
Object.keys()不能在<= IE8中使用(首先是引起麻烦的那些delete)。另外,您可能是指obj[key] = undefined在catch块内部。;]
WynandB 2014年

就是这样!修改。
Mikebert4 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.