Javascript 里的 in


  寫js的時候需要遍歷一個對象的屬性,把屬性名和屬性值都提出來,之前沒遇到這種需求,查了一下可以用for in的方式.

var obj = {
    "key1":"value1",
    "key2":"value2",
    "key3":"value3"
};

function EnumaKey(){
	for(var key in obj ){
		alert(key);
    }
}

function EnumaVal(){
	for(var key in obj ){
		alert(obj[key]);
    }
}

數組也可以這樣遍歷,但不推薦,因為不能保證順序,而且如果在Array的原型上添加了屬性,這個屬性也會被遍歷出來。

for-in循環應該用在非數組對象的遍歷上,使用for-in進行循環也被稱為“枚舉”。

從技術上將,你可以使用for-in循環數組(因為JavaScript中數組也是對象),但這是不推薦的。因為如果數組對象已被自定義的功能增強,就可能發生邏輯錯誤。另外,在for-in中,屬性列表的順序(序列)是不能保證的。所以最好數組使用正常的for循環,對象使用for-in循環。

有個很重要的hasOwnProperty()方法,當遍歷對象屬性的時候可以過濾掉從原型鏈上下來的屬性。

思考下面一段代碼:

// 對象
var man = {
   hands: 2,
   legs: 2,
   heads: 1
};

// 在代碼的某個地方
// 一個方法添加給了所有對象
if (typeof Object.prototype.clone === "undefined") {
   Object.prototype.clone = function () {};
}

在這個例子中,我們有一個使用對象字面量定義的名叫man的對象。在man定義完成后的某個地方,在對象原型上增加了一個很有用的名叫 clone()的方法。此原型鏈是實時的,這就意味着所有的對象自動可以訪問新的方法。為了避免枚舉man的時候出現clone()方法,你需要應用hasOwnProperty()方法過濾原型屬性。如果不做過濾,會導致clone()函數顯示出來,在大多數情況下這是不希望出現的。

// 1.
// for-in 循環
for (var i in man) {
   if (man.hasOwnProperty(i)) { // 過濾
      console.log(i, ":", man[i]);
   }
}
/* 控制台顯示結果
hands : 2
legs : 2
heads : 1
*/

// 2.
// 反面例子:
// for-in loop without checking hasOwnProperty()
for (var i in man) {
   console.log(i, ":", man[i]);
}
/*
控制台顯示結果
hands : 2
legs : 2
heads : 1
clone: function()
*/

另外一種使用hasOwnProperty()的形式是取消Object.prototype上的方法。像這樣:

for (var i in man) {
   if (Object.prototype.hasOwnProperty.call(man, i)) { // 過濾
      console.log(i, ":", man[i]);
   }
}

其好處在於在man對象重新定義hasOwnProperty情況下避免命名沖突。也避免了長屬性查找對象的所有方法,你可以使用局部變量“緩存”它。

var i, hasOwn = Object.prototype.hasOwnProperty;
for (i in man) {
    if (hasOwn.call(man, i)) { // 過濾
        console.log(i, ":", man[i]);
    }
}

嚴格來說,不使用hasOwnProperty()並不是一個錯誤。根據任務以及你對代碼的自信程度,你可以跳過它以提高些許的循環速度。但是當你對當前對象內容(和其原型鏈)不確定的時候,添加hasOwnProperty()更加保險些。

--------------------------------------------------------------------------------------------------------------------------------------------------------------

javascript中in關鍵字還有下面的作用

定義:

in操作符用來判斷某個屬性屬於某個對象,可以是對象的直接屬性,也可以是通過prototype繼承的屬性。(參見hasOwnProperty)

注意事項:

對於一般的對象屬性需要用字符串指定屬性的名稱

如:
var mycar = {make: "Honda", model: "Accord", year: 1998};
"make" in mycar  // returns true
"model" in mycar // returns true

 

對於數組屬性需要指定數字形式的索引值來表示數組的屬性名稱(固有屬性除外,如length)。

// Arrays
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
0 in trees        // returns true
3 in trees        // returns true
6 in trees        // returns false
"bay" in trees    // returns false (you must specify the index number,
                  // not the value at that index)
"length" in trees // returns true (length is an Array property)
 

in的右邊必須是一個對象,如:你可以指定一個用String構造器生成的,但是不能指定字符串直接量的形式:

var color1 = new String("green");
"length" in color1 // returns true
var color2 = "coral";
"length" in color2 // generates an error (color is not a String object)
 

如果你使用delete操作符刪除了一個屬性,再次用in檢查時,會返回false,如:

var mycar = {make: "Honda", model: "Accord", year: 1998};
delete mycar.make;
"make" in mycar;  // returns false
 
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
delete trees[3];
3 in trees; // returns false

 

如果你把一個屬性值設為undefined,但是沒有使用delete操作符,使用in檢查,會返回true.

var mycar = {make: "Honda", model: "Accord", year: 1998};
mycar.make = undefined;
"make" in mycar;  // returns true

 

var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
trees[3] = undefined;
3 in trees; // returns true


免責聲明!

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



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