談談js中for in 需要注意的地方


js中for in 可以遍歷對象或數組的顯性屬性,也就是說我們自己定義的屬性是可以遍歷的,那些原型上默認已有的屬性,例如:Object.prototype.toString、Object.prototype.hasOwnProperty 是遍歷不出來的。

for in 的基本規則如上,不過還有“坑”的地方需要我們注意:

1、for in循環出的值不一定是按順序的。代碼如下:

var b = {3:1,42:2,11:3}
for( var key in b ){
    alert( b[key] )
}

低版本瀏覽器彈窗的順序是:1、2、3。現代瀏覽器彈窗的順序是1、3、2。

2、在原型上加擴展方法,會被for in 出來。代碼如下:

Object.prototype.test = "I am test"
var b = {"name":"txj"}
for( var key in b ){
    alert(key + " : "+ b[key])
}

我們手動加在原型上的方法,for in的時候會被遍歷出來。一般我們遍歷對象並不需要其原型的屬性,所以遍歷時最好Object.prototype.hasOwnProperty方法進行判斷。

3、在實例中定義原型中已有的方法,瀏覽器for in 情況不一致。代碼如下:

var b = {"name":"txj"}
b.toString = function(){ alert("I am toString") }
for( var key in b ){
    alert(key + " : "+ b[key])
}

我們給b實例加了一個原型上已有的方法toString。現代瀏覽器能循環出toString 低版本瀏覽器卻不能。所以給實例定屬性名時,不要和原型已有的一致。

4、各瀏覽器循環出的屬性順序不同。代碼與2中的一樣:

Object.prototype.test = "I am test"
var b = {"name":"txj"}
for( var key in b ){
    alert(key + " : "+ b[key])
}

現代瀏覽器先循環實例中的屬性,再循環原型中的屬性。低版本瀏覽器相反。

這讓我想到了jQuery對$.isPlainObject()方法實現的一段代碼:

// Own properties are enumerated firstly, so to speed up,
// if last one is own, then all properties are own.
var key
for ( key in obj ) {}
return key === undefined || hasOwn.call( obj, key );

它這里說如果一個對象的最后一個屬性是實例自己的屬性,那么所有的屬性都是實例自己的屬性。這對低版本瀏覽器來說應該是不對的。所以jquery后來又加了如下代碼修復:

// Support: IE<9
// Handle iteration over inherited properties before own properties.
if ( support.ownLast ) {
    for ( key in obj ) {
        return hasOwn.call( obj, key );
    }
}

最后想吐槽一下,一般不要在原型上加自定義方法;數組的循環一般不用for in 。哈哈!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM