9

我想我在 IE (IE8) 处理 for-in javascript 语句时发现了一个错误。经过几个小时将其归结为一个小示例后,看起来 IE 在 for-in 循环中专门跳过了任何名为“toString”的属性——无论它是在原型中还是对象的“自己的属性”。

我把我的测试代码放在这里

function countProps(obj) {
    var c = 0;
    for (var prop in obj) {
        c++;
    }
    return c;
}

var obj = {
    toString: function() {
        return "hello";
    }
};

function test() {
    var o = "";
    var d = document.getElementById('output');

    o += "<br/>obj.hasOwnProperty('toString') == " + obj.hasOwnProperty('toString');
    o += "<br/>countProps(obj) = " + countProps(obj);
    o += "<br/>obj.toString() = " + obj.toString();

    d.innerHTML = o;
}

这应该产生:

obj.hasOwnProperty('toString') == true
countProps(obj) = 1
obj.toString() = hello

但在 IE 中,我得到:

obj.hasOwnProperty('toString') == true
countProps(obj) = 0
obj.toString() = hello

任何名为“toString”的属性的特殊外壳正在破坏我的代码,它试图将方法复制到 Function.prototype 中——我的自定义 toString 函数总是被跳过。

有谁知道解决方法?这是某种仅限于怪癖模式的行为 - 还是只是一个 BUG?

4

2 回答 2

10

是的,这是一个错误。看到这个答案

引用CMS

另一个众所周知的 JScript 错误是“DontEnum 错误”,如果一个对象在其作用域链中包含一个不可枚举的属性(具有 { DontEnum } 属性),如果该属性被其他对象隐藏,它将保持为非可枚举的,例如:

var dontEnumBug = {toString:'foo'}.propertyIsEnumerable('toString');

它会在 IE 上评估为 false,这在使用 for-in 语句时会导致问题,因为不会访问属性。

于 2010-09-14T00:42:41.457 回答
2

这是 IE 中的一个错误,也适用于名为valueOf.

您可以像这样解决它:

if(obj.toString !== Object.prototype.toString || obj.hasOwnProperty("toString"))
    //Handle it
if(obj.valueOf !== Object.prototype.valueOf || obj.hasOwnProperty("valueOf"))
    //Handle it
于 2010-09-14T00:57:47.173 回答