【问题标题】:Deleting a window property in IE在 IE 中删除窗口属性
【发布时间】:2010-11-07 14:06:59
【问题描述】:

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

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

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

【问题讨论】:

  • 为了清楚起见,因为看起来没有人在任何答案中实际说过:这是 Internet Explorer 中的一个 错误。 1999(第 3 版)规范中没有任何内容允许从 delete 引发异常,即使该属性不存在或不可删除(您的 window.x 在任何情况下都不应出现),而新的第 5 版版本规范只允许在新的严格模式下从delete 抛出异常。在这方面,window 没有什么特别之处。然而,在 2010 年,IE8 中的 JScript 引擎仍然出现了这个错误。sigh
  • T.J. Crowder,window 不是一个对象,它是根命名空间的访问器。它没有这样的属性,所以当你在它上面运行 delete 时,例如在这种情况下,它没有义务以任何理由实际删除它们。在对象名称上设置 undefined 很好,因为 gc 将通过并消除未引用的对象。希望这有助于理解这里的实际问题,以及为什么这不是一个错误,因为它对于正在缓慢更新以实现现代化的语言来说是一个糟糕的实现选择

标签: javascript internet-explorer properties window


【解决方案1】:

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

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

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

有人问,为什么不直接赋值 undefined?如果您想稍后枚举密钥,这很重要(尽管如果您依赖解决方法,密钥枚举仍然不会做您想要的......)。但无论如何,要强调删除和简单地分配 undefined (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 

【讨论】:

  • 当我向他们展示这个解决方案时,一位同事问了一个很好的问题:为什么不跳过中间人并将删除调用替换为未定义的分配?
  • 好问题,我花了一年的时间才遇到一个差异很重要的案例。
【解决方案2】:

我会这样做:

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

【讨论】:

  • 谢谢,这就是我最后所做的。它在 IE 中抛出异常,但它被捕获并且没有造成任何损坏。
  • 我见过最深入的delete解释在这里,这是IE部分。 (以防将来有人遇到更复杂的问题)perfectionkills.com/understanding-delete/#ie_bugs
【解决方案3】:

这有帮助吗?

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

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

【讨论】:

  • 不幸的是,这并没有从内存中删除变量,它只是给它一个空值,但据我所知,这是唯一的选择。
  • 谢谢。我更进一步并使用了 window.x = undefined。这仍然不是我想要的,但它会做。奇怪的是我在网上没有找到任何有用的信息。
【解决方案4】:

我在处理缓存我自己的数据时实现了这个解决方案 - 数据并没有太多缓存的频率,以至于内存泄漏可能已经成为一个问题。这很昂贵,但定期重新映射对象是确保它不会失控的最简单方法。

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}   

希望这对某些人有用!

【讨论】:

  • Object.keys() 将无法在 delete 出现问题)。此外,您可能指的是 catch 块内的obj[key] = undefined。 ;]
  • 就是这样!修订。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多