簡體   English   中英

JavaScript中for循環和for-in循環之間的區別

[英]difference between for loop and for-in loop in javascript

我發現javascript中的for循環和for-in循環之間有區別。

當我定義一個新數組時:

var a=new Array();

然后例如但不連續地添加一些值:

a[0]=0;a[1]=1;a[4]=4; 

當我使用for(i=0;i<5;i++)獲取值並使用alert顯示它時,它與使用for(i in a)

前一個將顯示索引2,3中的元素,該元素顯示“未定義”,而for-in將僅顯示索引0,1和4。有人可以告訴我為什么嗎?

For循環遍歷它們,直到i達到5,因此i = 0、1、2、3、4、5並遍歷所有。 但是,使用for ... in循環僅迭代其屬性,而不是0到5,而是您定義的0,1,4。

MDN

注意: for..in不應用於遍歷索引順序很重要的Array。

數組索引只是具有整數名稱的可枚舉屬性,其他方面與常規Object屬性相同。 無法保證for ... in將以任何特定順序返回索引,並且將返回所有可枚舉的屬性,包括具有非整數名稱的屬性和被繼承的屬性。

因為迭代的順序取決於實現,所以在數組上進行迭代可能不會以一致的順序訪問元素。 因此,在訪問順序很重要的數組上進行迭代時,最好使用帶有數字索引的for循環(或Array.forEach或for ... of循環)。

for (... in ...)通常用於遍歷對象的屬性(這是javaScript用於關聯數組的屬性),而典型的for循環用於順序數組。

在您的示例中,您實際上是在用鍵0、1和4創建一個關聯數組。如果要使用真正的javaScript數組,則可以使用a.push(0)a.push(1)等。 。為了添加值, 順序地 ,在陣列上的端部。

對於順序數組,語法for (var i = 0; i < arr.length; i++)使i計數從0到1小於數組的長度。 這將使i一一等於數組中的每個索引,從而允許您訪問該數組中的每個元素。

但是,對於關聯數組,鍵是非順序鍵,因此使變量計數“比數組長度小0到1”將不會產生期望的結果。 在您的示例中,由於您手動創建的鍵恰好是0、1和4(幾乎是連續的),因此已接近正常工作。

如果您想要一個帶有非順序鍵的數組(例如“ 0”,“ 1”,“ 4”等“非連續”鍵),則應該使用對象而不是數組,例如

var obj = {};
obj[0] = 0;
obj[1] = 1;
obj[4] = 4;

然后使用for (... in ...)循環將是正確的語法。

for-in循環枚舉變量的可枚舉屬性。 對於您的數組,將“ 0”,“ 1”和“ 4”作為可枚舉屬性添加到數組中。 因此,for-in循環在“ i”中僅獲得0、1和4。

for循環適用於i = 0至5。因此,您也嘗試訪問2和3處的值,這些值顯然是未定義的。

語法

for (var k in obj)

實際上是一個for-each循環。 它遍歷對象的屬性。 您應該熟悉JavaScript對象。 對象是鍵到值的映射。

因此,for-each循環對對象非常有用。 但是,在遍歷數組時,最好使用常規的for循環。

這是在對象的屬性上使用的for-each循環的示例: http : //jsfiddle.net/nbtLpw0z/

我使用的是for-in循環,因為它是一種較短的形式,但是有時您可能希望控制迭代變量。 例如,如果要遍歷偶數索引,則需要使用常規的for循環:

for (var i = 0; i < myarray.length; i+=1) {...}

例如,如果要向后迭代,則同樣適用:

for (var i = myarray.length-1; i >= 0; i--) {...}

當然,對於對象,for-in循環允許您在迭代變量中獲取屬性名稱。

 var obj = {year: 2014, city: "Surat"}
 for (var propn in obj) alert(propn + " = " + obj[propn]);

在您的示例中,我將使用for-in,因為您正在執行簡單的迭代。 而且我認為在未優化的Javascript編譯器/解釋器中,for-in循環會更快,因為變量增量是在內部完成的。

對於初學者來說for in Array上使用for in循環是沒有意義的for in因為JavaScript中的數組只能具有有序的數字索引。 因此,您可以在0array.length - 1之間的任何索引處訪問數組,如果您想使用for in循環遍歷數組,您當然可以,但是,常規的for循環更合適。

如果您沒有訂購數字索引,則使用for in循環。 JavaScript對象實際上是一個有序哈希表。 您可以使用in操作符訪問JavaScript對象的鍵,該操作符返回對象的鍵,並通過訪問該鍵的對象來獲取值。

例如:

var obj = {
   hello: "world",
   world: "hello"
};

常規的for循環不起作用,因此您無需使用for in循環。

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

對象也不會返回足夠准確的length屬性以迭代整個對象,因此for in循環是絕對必要的。

還要注意,通過不按下一個空閑元素的存在順序為數組分配值,將自動在您跳過的元素中放置undefined

在您的示例中,數組如下所示:

[0, 1, undefined × 2, 4]

for-each環被推薦用於遍歷對象屬性,而for循環被推薦用於陣列。 您可以使用push()獲得相同的結果。

 var a = []; //recommended way of declaring arrays over `new Arrays()` a.push(0); a.push(1); a.push(4); //usual for-loop for (var i = 0; a.length > i; i++) //recommended console.log('a[', i, ']=', a[i]); console.log('---------------------'); // for-each loop for (var k in a) //not recommended console.log('a[', k, ']=', a[k]); console.log('---------------------'); 
 Open console... 

 var person = { 'name': 'Adam' }; for (var k in person) console.log('person.' + k, '=', person[k]); console.log('----------------------'); person.age = 26; //new property for (var k in person) console.log('person.' + k, '=', person[k]); console.log('----------------------'); person['gender'] = 'Male'; //again a new property for (var k in person) console.log('person.' + k, '=', person[k]); console.log('----------------------'); person.name = 'Will'; //updating property for (var k in person) console.log('person.' + k, '=', person[k]); console.log('----------------------'); 
 Open console... 

在幕后,for-in循環不過是for循環。 For(i in x)分解為-

for(i=0;i<x.length;i++) {
if(x[i] != undefined)
console.log(x[i]);
}

我已經閱讀並聽到了正常的for循環: for(var i = 0; i < arr.length; i++)更快。 但是我會說for of使用:

var arr = [1,2,3], obj = {x: 1, y:2};
for(var value of arr) console.log(value) // 1, 2, 3
for(var key in obj) console.log(key) // x, y
for(var key of Object.keys(obj)) console.log(key) // x, y

您可以使用Object.keys(obj)將對象的鍵轉換為數組,並在其上調用Array.prototype方法

您的“ for”循環從0-4開始查看數組索引的所有值,因為這正是您要執行的操作。 因此,它先查看a [0]並找到一個值,然后找到a [1](相同的交易),然后轉到a [2]並意識到您從未為a [2]初始化一個值,因此未定義。 a [3]也是一樣,最后a [4]具有一個值,以便找到它。

這種“ for”循環的類型將檢查每個索引是否已定義。

“ for ... in ...”循環將僅檢查初始化值。 您的數組具有3個已初始化的值,因此它將檢查這些值。 它將按照索引的順序向您顯示,但是索引實際上並不會影響它的外觀。 因此,如果將“ a [1]”更改為“ a [3]”,將“ a [4]”更改為“ a [10]”,則將“。”使用時仍會得到完全相同的答案。 。in ...”循環中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM