2011-11-04 81 views
3

我是JavaScript新手,目前我正在學習所謂的for... in循環。適用於JavaScript循環嗎?

在JavaScript中編碼時,實際上是否使用這些循環?

我可以看到所有其他類型的循環是如何有用 - 但不是這一個。

有人對此有所瞭解,請儘可能包含真實生活中的示例。

回答

7

僅在Javascript中可以使用正常的for(;;)循環迭代Array對象。該for..in用於非數組對象的枚舉:

for (var i in obj) { 
    if (obj.hasOwnProperty(i)) { // if you don't want to access prototype properties 
     alert(i); 
     alert(obj[i]); 
    } 
} 
+0

同意約hasOwnProperty(),但你也可能要檢查的typeof(),以確保功能類型等別你最終會輸出。 –

+0

@MickSear完全取決於你對對象做什麼。例如,如果你使用遍歷來「克隆」對象,那麼你並不在乎。無論如何,我只是添加了它,因爲這是他可能遇到的問題,與問題本身並沒有真正的關係。 – deviousdodo

+0

就像一個筆記:我的答案只是關於一般的做法,我忽略了一些技巧。 'arguments'是'只有數組對象可以被迭代'的一個例外,當然''for'循環只是偶爾用於遍歷數組,但我認爲這些事情對於這個問題本身並不重要。 – deviousdodo

0

它通常用於遍歷的東西集合。例如,因爲每個JavaScript對象都可以看作屬性的集合,所以可以按照這種方式枚舉屬性。

//let's loop throug all properties of a "document" 
//we don't know what these will be 
var txtProps = ""; 
for (var prop in window.document) { 
    txtProps += prop + "\n"; 
} 
alert(txtProps);//pops out a message showing a looong list of all properties 
0

我認爲沒關係,只要你明白一個對象可以容納的不僅僅是簡單的變量。考慮下面這個例子,從w3schools.com修改,以說明這一點:

<script type="text/javascript"> 

//This is probably as you expect: 
var person={fname:"John",lname:"Doe",age:25}; 

//This is probably unexpected and unwanted, but is valid and will be an output of the for...in loop: 
person.f = function(){ 
alert("Hi"); 
}; 

//Use typeof() function to check that the data type is what you expect: 
for (x in person){ 
    document.write(typeof(person[x]) + " "); 
} 

</script> 

此打印:

串串數字功能

要獲得關於環路類型,則對之間的差異具體問題()循環適用於具有length屬性的數組類型。 foreach()循環可以很好地用於迭代對象集合,而foreach ... in循環對於對象的鍵(對於任何類型的循環都不會聲稱這些是唯一用途)很適用。

0

爲了理解這一點,您首先需要了解JavaScript的對象模型。

正如你所指出的,當使用數組時,for...in循環並不是那麼有用,因爲for (;;)循環更容易完成這項工作。

但是數組只是一種具有數字屬性的JavaScript對象,並且for (;;)循環僅處理數字屬性。符號myArray[0]的原因是,您可以對任何屬性名稱使用此方括號表示法。因此myObject['myProperty']myObject.myProperty相同。這是for...in變成有用:

for (var i in myObject) { 
    alert(myObject[i]); 
} 

因此,如果我們想設置的唯一屬性是myProperty,然後i將等於"myProperty"(注意,這是一個字符串,這使得它不僅僅是作爲一個變量名更動態) 。

雖然這裏有一個巨大的但是。對象有一些叫做原型的東西,這些原型有自己的屬性和方法。如果我做到以下幾點:

for (var i in myArray) { 
    alert(i + ': ' + myArray[i]); 
} 

...我不會一下就驚動用數值(1,2,3等),我也會得到警告與陣列的屬性,如length,及其方法如join。這些特性實際上屬於Array對象的原型,原型屬性可以通過做被過濾了以下工作:

for (var i in myArray) { 
    if (myArray.hasOwnProperty(i)) { 
     alert(i + ': ' + myArray[i]); 
    } 
} 

現在我就把與數值再次提醒,這意味着這是(幾乎)完全相同與for (var i = 0;; i < myArray.length; i++)相同。爲什麼當我們能夠使用這種符號時,我告訴你這一點?因爲所有的對象都有原型,而不僅僅是數組。並且每個對象都從Object對象開始下降,因此如果有人定義了Object.prototype.myProperty = "some string value",那麼該對象總會出現在您在頁面的其餘部分使用的任何for...in循環中。謝天謝地,hasOwnProperty方法本身屬於Object.prototype,所以你可以(也應該)總是在你的for...in循環中使用它。

因此,這裏是一個完全成熟的for...in例如:

// This is just one way of defining an object. We could also use a constructor function, or `new Object()` 
var myObject = { 
    aProperty : "my first property value", 
    anotherProperty : "second property value" 
    4 : "numeric property names work too, you know" 
} 

for (var i in myObject) { 
    if (myObject.hasOwnProperty(i)) { 
     document.write(i + ': ' + myObject[i] + '<br />\n'); 
    } 
} 

輸出:

aProperty: my first property value 
anotherProperty: secondPropertyValue 
4: numeric property names work too, you know 

希望這可以解釋這一切。

0

for infor都用於特定目的。讓我們看看一些。

如果你有一個對象

var obj = { one: 1, two: 2 }; 

然後你可以遍歷它的使用for in循環特性即

for(var i in obj) console.log(obj[i]); //use obj.hasOwnProperty(i) to exclude prototype properties 

的注意,如果你試圖通過迭代obj for循環它將不會工作,因爲它會使用數字索引來訪問密鑰,並會給一個未定義的,即obj[0]將是未定義的。這不在於形成一個事實,即獲得一個對象的長度會比簡單地編寫obj.length更爲複雜。當然,如果你有數字屬性,你可以使用for循環,for in更適合用於對象迭代。

如果你有一個陣列

var array = [1,2] 

你可以在技術上使用這兩種我們建議您使用for循環這一點。這是爲什麼

  1. 元素順序不能保證。
  2. 原型屬性也會迭代,這可能會導致不需要的副作用。

爲了說明第二點,讓我們擴展Array。

Array.prototype.print_array = function(){ console.log(this) }; 

,我們只是添加到陣列該功能將所有的數組對象繼承,因此,通過for in

for(var i in array) console.log(array[i]); 

迭代陣列上會產生

1 
2 
function(){ console.log(this) } // the prototype property was iterated over also 

並遍歷在陣列上與for

for(var i =0; i < array.length; i++) console.log(array[i]); 

會產生預期的結果。

1 
2 

因此,對於對象重複使用for in和數組迭代使用for