javascript for in,for each,for循環遍歷區別


1、for...in 

以任意順序遍歷一個對象的可枚舉屬性。對於每個不同的屬性,語句都會被執行。

語法:

for (variable in object) {...}

參數:

variable
在每次迭代時,將不同的屬性名分配給 變量
object
被迭代其枚舉屬性的對象。

 

for..in 不應該被用來迭代一個下標順序很重要的 Array .

數組索引僅是可枚舉的整數名,其他方面和別的普通對象屬性沒有什么區別。for...in 並不能夠保證返回的是按一定順序的索引,但是它會返回所有可枚舉屬性,包括非整數名稱的和繼承的。

因為迭代的順序是依賴於執行環境的,所以數組遍歷不一定按次序訪問元素。 因此當迭代那些訪問次序重要的 arrays 時用整數索引去進行 for 循環 (或者使用 Array.prototype.forEach() 或 for...of 循環) 。

僅迭代自身的屬性

如果你只要考慮對象本身的屬性,而不是它的原型,那么使用 getOwnPropertyNames() 或執行  hasOwnProperty() 來確定某屬性是否是對象本身的屬性 (也能使用propertyIsEnumerable)。另外,如果你知道外部不存在任何的干擾代碼,你可以擴展內置原型與檢查方法。

例子

var obj = {a:1, b:2, c:3};
    
for (var prop in obj) {
  console.log("obj." + prop + " = " + obj[prop]);
}

// Output:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"
var triangle = {a:1, b:2, c:3};

function ColoredTriangle() {
  this.color = "red";
}

ColoredTriangle.prototype = triangle;

var obj = new ColoredTriangle();

for (var prop in obj) {
  if( obj.hasOwnProperty( prop ) ) {
    console.log("o." + prop + " = " + obj[prop]);
  } 
}

// Output:
// "o.color = red"

摘自https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...in#Description

2、for each...in

使用一個變量迭代一個對象的所有屬性值,對於每一個屬性值,有一個指定的語句塊被執行.

for each...in 是 ECMA-357 (E4X) 標准的一部分, 大部分非Mozilla瀏覽器都沒有實現該標准, E4X並不是 ECMAScript 標准的一部分.

作為ECMA-357(E4X)標准的一部分,for each...in語句已被廢棄,E4X中的大部分特性已被刪除,但考慮到向后兼容,for each...in只會被禁用而不會被刪除,可以使用ES6中新的for...of語句來代替.

語法:

for each (variable in object) {
  statement
}

參數:

variable
用來遍歷屬性值的變量,前面的 var關鍵字是可選的.該變量是函數的局部變量而不是語句塊的局部變量.
object
該對象的屬性值會被遍歷.
statement
遍歷屬性值時執行的語句. 如果想要執行多條語句, 請用( { ... }) 將多條語句括住.

 

一些對象的內置屬性是無法被遍歷到的,包括所有的內置方法,例如String對象的indexOf方法.不過,大部分的用戶自定義屬性都是可遍歷的.

警告:永遠不要使用for each...in語句遍歷數組,僅用來遍歷常規對象。

例子

var sum = 0;
var obj = {prop1: 5, prop2: 13, prop3: 8};

for each (var item in obj) {
  sum += item;
}

print(sum); // 輸出"26",也就是5+13+8的值

摘自https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for_each...in

3、for循環

用於創建一個循環,它包含了三個可選的表達式,三個可選的表達式包圍在圓括號中並由分號分隔,后面跟隨一個語句或一組語句在循環中執行.

語法:

for ([initialization]; [condition]; [final-expression])
   statement

參數:

initialization一個表達式 (包含賦值語句) 或者變量聲明。典型地被用於初始化一個計數器。該表達式可以使用var關鍵字聲明新的變量。初始化中的變量不是該循環的局部變量,而是與該循環處在同樣的作用域中。該表達式的結果無意義。

condition一個條件表達式被用於確定每一次循環是否能被執行。如果該表達式的結果為true, 循環體內的語句將被執行。 這個表達式是可選的。如果被忽略,那么就被認為永遠為true。如果計算結果為false,那么執行流程將被跳到for語句結構后面的第一條語句。

final-expression每次循環的最后都要執行的表達式。執行時機是在下一次condition的計算之前。通常被用於更新或者遞增計數器變量。

statement只要condition的結果為true就會被執行的語句。 要在循環體內執行多條語句,使用一個 block 結構 ({ ... }) 來包含要執行的語句。沒有任何語句要執行,使用一個 empty 語句 (;)。

一般使用

以下例子聲明了變量i並被初始賦值為0,for語句檢查i的值是否小於9,如果小於9,則執行語句塊內的語句,並且最后將i的值遞增。

for (var i = 0; i < 9; i++) {
   console.log(i);
   // more statements
}

忽略表達式

for語句的所有的表達式都是可選的

舉個例子,初始化語句(initialization)中的表達式沒有被指定:

var i = 0;
for (; i < 9; i++) {
    console.log(i);
    // more statements
}

就像initialization,condition也是可選的。如果你忽略了,為了不要創建了死循環(無限循環),你必須確保循環體內存在可以退出循環的語句,使用break。

for (var i = 0;; i++) {
   console.log(i);
   if (i > 3) break;
   // more statements
}

你當然可以忽略所有的表達式。同樣的,確保使用了 break 語句來退出循環並且你還需要修改(遞增)一個變量,以確保能夠正常執行break語句。

var i = 0;

for (;;) {
  if (i > 3) break;
  console.log(i);
  i++;
}

使用空語句的例子

以下為在[final-expression]部分中循環計算一個節點的偏移位置,它不需要執行一個語句或者一組語句,因此使用了空語句。

function showOffsetPos (sId) {
  var nLeft = 0, nTop = 0;

  for (var oItNode = document.getElementById(sId); // initialization
       oItNode; // condition
       nLeft += oItNode.offsetLeft, nTop += oItNode.offsetTop, oItNode = oItNode.offsetParent) // final-expression
       /* empty statement */ ;
  
  console.log("Offset position of \"" + sId + "\" element:\n left: " + nLeft + "px;\n top: " + nTop + "px;");
}

// Example call:

showOffsetPos("content");

// Output:
// "Offset position of "content" element:
// left: 0px;
// top: 153px;"

摘自https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for

 

4、forEach() 

forEach() 方法對數組的每個元素執行一次提供的函數。

let a = ['a', 'b', 'c'];

a.forEach(function(element) {
    console.log(element);
});

// a
// b
// c

語法:

array.forEach(callback(currentValue, index, array){
    //do something
}, this)

array.forEach(callback[, thisArg])

參數:

callback為數組中每個元素執行的函數,該函數接收三個參數:

currentValue(當前值)
數組中正在處理的當前元素。
index(索引)
數組中正在處理的當前元素的索引。
array
forEach()方法正在操作的數組。

thisArg可選可選參數。當執行回調 函數時用作this的值(參考對象)。

描述:

forEach 方法按升序為數組中含有效值的每一項執行一次callback 函數,那些已刪除(使用delete方法等情況)或者未初始化的項將被跳過(但不包括那些值為 undefined 的項)(例如在稀疏數組上)。

callback 函數會被依次傳入三個參數:

  • 數組當前項的值
  • 數組當前項的索引
  • 數組對象本身

如果給forEach傳遞了thisArg參數,當調用時,它將被傳給callback 函數,作為它的this值。否則,將會傳入 undefined 作為它的this值。callback函數最終可觀察到this值,這取決於 函數觀察到this的常用規則

forEach 遍歷的范圍在第一次調用 callback 前就會確定。調用forEach 后添加到數組中的項不會被 callback 訪問到。如果已經存在的值被改變,則傳遞給 callback 的值是 forEach 遍歷到他們那一刻的值。已刪除的項不會被遍歷到。如果已訪問的元素在迭代時被刪除了(例如使用 shift()) ,之后的元素將被跳過 - 參見下面的示例。

例子:

function logArrayElements(element, index, array) {
    console.log("a[" + index + "] = " + element);
}

// 注意索引2被跳過了,因為在數組的這個位置沒有項
[2, 5, ,9].forEach(logArrayElements);

// a[0] = 2
// a[1] = 5
// a[3] = 9

[2, 5,"" ,9].forEach(logArrayElements);
// a[0] = 2
// a[1] = 5
// a[2] = 
// a[3] = 9

[2, 5, undefined ,9].forEach(logArrayElements);
// a[0] = 2
// a[1] = 5
// a[2] = undefined
// a[3] = 9


let xxx;
// undefined

[2, 5, xxx ,9].forEach(logArrayElements);
// a[0] = 2
// a[1] = 5
// a[2] = undefined
// a[3] = 9
//從每個數組中的元素值中更新一個對象的屬性:
function
Counter() { this.sum = 0; this.count = 0; } Counter.prototype.add = function(array) { array.forEach(function(entry) { this.sum += entry; ++this.count; }, this); //console.log(this); }; var obj = new Counter(); obj.add([1, 3, 5, 7]); obj.count; // 4 === (1+1+1+1) obj.sum; // 16 === (1+3+5+7)

因為thisArg參數 (this) 傳給了forEach(),每次調用時,它都被傳給callback函數,作為它的this值。

 

 

摘自https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

 5、for...of

 ECMAScript 6新方法,使用時參考https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...of

 


免責聲明!

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



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