我是JavaScript新手,目前我正在學習所謂的for... in
循環。適用於JavaScript循環嗎?
在JavaScript中編碼時,實際上是否使用這些循環?
我可以看到所有其他類型的循環是如何有用 - 但不是這一個。
有人對此有所瞭解,請儘可能包含真實生活中的示例。
我是JavaScript新手,目前我正在學習所謂的for... in
循環。適用於JavaScript循環嗎?
在JavaScript中編碼時,實際上是否使用這些循環?
我可以看到所有其他類型的循環是如何有用 - 但不是這一個。
有人對此有所瞭解,請儘可能包含真實生活中的示例。
僅在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]);
}
}
它通常用於遍歷的東西集合。例如,因爲每個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
我認爲沒關係,只要你明白一個對象可以容納的不僅僅是簡單的變量。考慮下面這個例子,從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循環對於對象的鍵(對於任何類型的循環都不會聲稱這些是唯一用途)很適用。
爲了理解這一點,您首先需要了解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
希望這可以解釋這一切。
for in
和for
都用於特定目的。讓我們看看一些。
如果你有一個對象
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循環這一點。這是爲什麼
爲了說明第二點,讓我們擴展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
同意約hasOwnProperty(),但你也可能要檢查的typeof(),以確保功能類型等別你最終會輸出。 –
@MickSear完全取決於你對對象做什麼。例如,如果你使用遍歷來「克隆」對象,那麼你並不在乎。無論如何,我只是添加了它,因爲這是他可能遇到的問題,與問題本身並沒有真正的關係。 – deviousdodo
就像一個筆記:我的答案只是關於一般的做法,我忽略了一些技巧。 'arguments'是'只有數組對象可以被迭代'的一個例外,當然''for'循環只是偶爾用於遍歷數組,但我認爲這些事情對於這個問題本身並不重要。 – deviousdodo