IE 中对 toString 的双重标准

使用 for .. in 遍历对象,似乎没什么好说的,不过还是有例外。在各个浏览器里面跑下面的代码:

var obj = {
    toString: function() {
        return "custom.toString()";
    }
}
for(var i in obj) {
    alert(i);
}

它们都会 alert 一个 toString,除了 IE。一开始还以为是加载慢,后来才认识到,其实 IE 并不把它当成是一个自定义的对象方法。同样的情况也发生在 valueOf() 方法上,可以猜想,IE 可能把它当成是 native 的了。
Quick Fix – Internet Explorer and toString problems 里面,介绍了使用条件注释(conditional comment)的方法来解决。

/*@cc_on
if(obj.toString!==Object.prototype.toString){
    // doStuff
}
if(obj.valueOf!==Object.prototype.valueOf){
    // doStuff
}
@*/

但是,IE 就真的把它当成了 native 的了吗?

obj.hasOwnProperty("toString"); // === true

通过 hasOwnProperty,它似乎又是知道 toString 实际上是一个自定义属性。那么,情况就变得更加怪异了,只能说 IE 在两种情况下处理的依据是不一样的,又或者说这就是一个 bug。
要处理这个例外,除了使用条件注释,还可以使用下面的方式:

if ($.browser.msie) {
    if (obj.hasOwnProperty("toString")) {
        // do have a toString
    }
    if (obj.hasOwnProperty("valueOf")) {
        // do have a valueOf
    }
}