[英]Loop through an array in JavaScript
在Java中,可以使用for
循環遍歷數組中的對象,如下:
String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray) {
// Do something
}
我可以在 JavaScript 中做同樣的事情嗎?
三個主要選項:
for (var i = 0; i < xs.length; i++) { console.log(xs[i]); }
xs.forEach((x, i) => console.log(x));
for (const x of xs) { console.log(x); }
詳細示例如下。
for
循環: var myStringArray = ["Hello","World"]; var arrayLength = myStringArray.length; for (var i = 0; i < arrayLength; i++) { console.log(myStringArray[i]); //Do something }
優點
break
和continue
流控制語句缺點
Array.prototype.forEach
: ES5規范引入了很多有益的數組方法。 其中之一Array.prototype.forEach
為我們提供了一種迭代數組的簡潔方法:
const array = ["one", "two", "three"] array.forEach(function (item, index) { console.log(item, index); });
在編寫 ES5 規范發布(2009 年 12 月)時已經將近十年了,它已被桌面、服務器和移動環境中的幾乎所有現代引擎實現,因此使用它們是安全的。
並且使用 ES6 箭頭函數語法,它更加簡潔:
array.forEach(item => console.log(item));
除非您計划支持古老的平台(例如, Internet Explorer 11 ),否則箭頭函數也被廣泛實現; 你也可以安全前往。
優點
缺點
break
/ continue
通常,您可以通過在迭代數組元素之前過濾它們來代替break
命令式循環的需要,例如:
array.filter(item => item.condition < 10)
.forEach(item => console.log(item))
請記住,如果您正在迭代一個數組以從中構建另一個數組,您應該使用map
。 我已經多次看到這種反模式。
反模式:
const numbers = [1,2,3,4,5], doubled = [];
numbers.forEach((n, i) => { doubled[i] = n * 2 });
地圖的正確用例:
const numbers = [1,2,3,4,5]; const doubled = numbers.map(n => n * 2); console.log(doubled);
此外,如果您嘗試將數組歸約為一個值,例如,您想對一個數字數組求和,則應使用reduce方法。
反模式:
const numbers = [1,2,3,4,5];
const sum = 0;
numbers.forEach(num => { sum += num });
正確使用reduce :
const numbers = [1,2,3,4,5]; const sum = numbers.reduce((total, n) => total + n, 0); console.log(sum);
for-of
語句: ES6標准引入了可迭代對象的概念,並定義了一種用於遍歷數據的新結構,即for...of
語句。
該語句適用於任何類型的可迭代對象,也適用於生成器(任何具有\[Symbol.iterator\]
屬性的對象)。
數組對象是 ES6 中定義的內置可迭代對象,因此您可以對它們使用以下語句:
let colors = ['red', 'green', 'blue'];
for (const color of colors){
console.log(color);
}
優點
break
/ continue
)。缺點
for...in
@zipcodeman 建議使用for...in
語句,但對於迭代數組for-in
應該避免,該語句旨在枚舉對象屬性。
它不應該用於類似數組的對象,因為:
第二點是它會給您帶來很多問題,例如,如果您擴展Array.prototype
對象以在其中包含一個方法,那么該屬性也會被枚舉。
例如:
Array.prototype.foo = "foo!"; var array = ['a', 'b', 'c']; for (var i in array) { console.log(array[i]); }
上面的代碼將控制台記錄“a”、“b”、“c”和“foo!”。
如果您使用一些嚴重依賴原生原型增強的庫(例如MooTools ),這可能會成為一個特別的問題。
正如我之前所說, for-in
語句用於枚舉對象屬性,例如:
var obj = { "a": 1, "b": 2, "c": 3 }; for (var prop in obj) { if (obj.hasOwnProperty(prop)) { // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety... console.log("prop: " + prop + " value: " + obj[prop]) } }
在上面的示例中, hasOwnProperty
方法允許您僅枚舉自己的屬性。 就是這樣,只有對象物理具有的屬性,沒有繼承的屬性。
我建議您閱讀以下文章:
是的,假設您的實現包括ECMAScript 2015 (“Harmony”版本)中引入的for
... of
功能...這是一個非常安全的假設。
它是這樣工作的:
// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
// ... do something with s ...
}
或者更好的是,因為 ECMAScript 2015 還提供了塊范圍的變量:
// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
// ... do something with s ...
}
// s is no longer defined here
(變量s
在每次迭代中都是不同的,但仍然可以在循環體中聲明為const
,只要它沒有在那里被修改。)
關於稀疏數組的注意事項:JavaScript 中的數組實際上可能存儲的項目數可能沒有它的length
報告的那么多; 該報告的數字僅比存儲值的最高索引大一。 如果數組包含的元素少於其長度所指示的元素,則稱其為sparse 。 例如,擁有一個僅在索引 3、12 和 247 處包含項目的數組是完全合法的; 這種數組的length
報告為 248,盡管它實際上只存儲了 3 個值。 如果您嘗試訪問任何其他索引處的項目,則該數組將在那里出現undefined
的值。 所以當你想“遍歷”一個數組時,你有一個問題要回答:你是想遍歷它的長度所指示的整個范圍並為任何缺失的元素處理undefined
s,還是只想處理元素實際存在? 這兩種方法都有很多應用。 這僅取決於您使用數組的目的。
如果您使用for
.. of
遍歷數組,則循環體將執行length
次,並且對於數組中實際不存在的任何項目,循環控制變量都設置為undefined
。 根據您“使用”代碼的詳細信息,該行為可能是您想要的,但如果不是,您應該使用不同的方法。
當然,一些開發人員別無選擇,只能使用不同的方法,因為無論出於何種原因,他們的目標是一個還不for
... of
.
只要您的 JavaScript 實現符合 ECMAScript 規范的先前版本(例如,排除了 Internet Explorer 9 之前的版本),您就可以使用Array#forEach
迭代器方法而不是循環。 在這種情況下,您傳遞一個要在數組中的每個項目上調用的函數:
var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) {
// ... do something with s ...
} );
與for
... of
不同, .forEach
僅調用數組中實際存在的元素的函數。 如果傳遞我們假設的具有三個元素且長度為 248 的數組,它只會調用該函數 3 次,而不是 248 次。 它還區分缺失元素和實際設置為undefined
的元素; 對於后者,它仍然會調用函數,傳遞undefined
作為參數。 如果這是您想要處理稀疏數組的方式,那么即使您的解釋器for
... of
, .forEach
也可能是可行的方法。
最后一個適用於所有JavaScript 版本的選項是顯式計數循環。 您只需從 0 數到比長度小一,然后使用計數器作為索引。 基本循環如下所示:
var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
s = myStringArray[i];
// ... do something with s ...
}
這種方法的一個優點是您可以選擇如何處理稀疏數組; 上面的代碼將循環體運行全length
,對於任何缺失的元素, s
設置為undefined
,就像for
.. of
一樣。 如果您只想處理稀疏數組中實際存在的元素,例如.forEach
,您可以在索引上添加一個簡單in
測試:
var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
if (i in myStringArray) {
s = myStringArray[i];
// ... do something with s ...
}
}
將長度值分配給局部變量(而不是在循環條件中包含完整的myStringArray.length
表達式)可以顯着提高性能,因為它每次都會跳過屬性查找; 在我的機器上使用 Rhino,加速是 43%。
您可能會在循環初始化子句中看到長度緩存,如下所示:
var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {
如果需要,顯式計數循環還意味着您可以訪問每個值的索引。 索引也作為額外參數傳遞給您傳遞給forEach
的函數,因此您也可以通過這種方式訪問它:
myStringArray.forEach( function(s, i) {
// ... do something with s and i ...
});
for
... of
不會為您提供與每個對象關聯的索引,但只要您要迭代的對象實際上是一個Array
( for
.. of
適用於可能沒有此方法的其他可迭代類型),您可以使用Array#entries方法將其更改為 [index, item] 對的數組,然后對其進行迭代:
for (const [i, s] of myStringArray.entries()) {
// ... do something with s and i ...
}
其他人提到的for
... in
語法是用於循環對象的屬性; 由於 JavaScript 中的 Array 只是一個具有數字屬性名稱的對象(以及一個自動更新的length
屬性),因此理論上您可以使用它遍歷 Array。 但問題是它並不局限於數字屬性值(請記住,即使方法實際上只是其值為閉包的屬性),也不能保證按數字順序迭代那些。 因此, for
... in
語法不應該用於遍歷數組。
您可以使用map
,這是一種函數式編程技術,在Python和Haskell等其他語言中也可用。
[1,2,3,4].map( function(item) {
alert(item);
})
一般語法是:
array.map(func)
通常func
會接受一個參數,它是數組的一項。 但在 JavaScript 的情況下,它可以采用第二個參數,即項目的索引,以及第三個參數,即數組本身。
array.map
的返回值是另一個數組,所以你可以這樣使用它:
var x = [1,2,3,4].map( function(item) {return item * 10;});
現在 x 是[10,20,30,40]
。
您不必內聯編寫函數。 它可以是一個單獨的功能。
var item_processor = function(item) {
// Do something complicated to an item
}
new_list = my_list.map(item_processor);
這將相當於:
for (item in my_list) {item_processor(item);}
除了你沒有得到new_list
。
(直接回答你的問題:現在你可以了!)
大多數其他答案都是正確的,但他們沒有提到(在撰寫本文時) ECMAScript
6
2015帶來了一種新的迭代機制,即for..of
循環。
這種新語法是在 JavaScript 中迭代數組的最優雅的方式(只要您不需要迭代索引)。
它目前適用於 Firefox 13+、Chrome 37+,並且本身不適用於其他瀏覽器(請參閱下面的瀏覽器兼容性)。 幸運的是,我們有 JavaScript 編譯器(例如Babel ),可以讓我們在今天使用下一代功能。
它也適用於 Node.js(我在 0.12.0 版本上對其進行了測試)。
迭代數組
// You could also use "let" or "const" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) {
console.log(letter);
}
迭代對象數組
const band = [
{firstName : 'John', lastName: 'Lennon'},
{firstName : 'Paul', lastName: 'McCartney'}
];
for(const member of band){
console.log(member.firstName + ' ' + member.lastName);
}
迭代生成器:
(示例摘自https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of )
function* fibonacci() { // A generator function
let [prev, curr] = [1, 1];
while (true) {
[prev, curr] = [curr, prev + curr];
yield curr;
}
}
for (const n of fibonacci()) {
console.log(n);
// Truncate the sequence at 1000
if (n >= 1000) {
break;
}
}
兼容性表: http: //kangax.github.io/compat-table/es6/#test-for..of_loops
規范: http ://wiki.ecmascript.org/doku.php?id=harmony:iterators
在 JavaScript 中,不建議使用 for-in 循環遍歷 Array,但最好使用for
循環,例如:
for(var i=0, len=myArray.length; i < len; i++){}
它也經過優化(“緩存”數組長度)。 如果您想了解更多信息, 請閱讀我關於該主題的帖子。
Opera、Safari、Firefox 和 Chrome 現在都共享一組增強的 Array 方法,用於優化許多常見的循環。
您可能不需要所有這些,但它們可能非常有用,或者如果每個瀏覽器都支持它們的話。
Mozilla Labs 發布了他們和WebKit都使用的算法,因此您可以自己添加它們。
過濾器返回滿足某些條件或測試的項目數組。
如果每個數組成員都通過了測試,則 each 返回 true。
如果有任何通過測試,則some返回 true。
forEach在每個數組成員上運行一個函數並且不返回任何內容。
map類似於 forEach,但它返回一個包含每個元素的操作結果的數組。
這些方法都采用一個函數作為它們的第一個參數,並有一個可選的第二個參數,這是一個對象,您希望在數組成員循環通過函數時將其范圍強加於它們。
忽略它,直到你需要它。
indexOf和lastIndexOf找到與其參數完全匹配的第一個或最后一個元素的適當位置。
(function(){
var p, ap= Array.prototype, p2={
filter: function(fun, scope){
var L= this.length, A= [], i= 0, val;
if(typeof fun== 'function'){
while(i< L){
if(i in this){
val= this[i];
if(fun.call(scope, val, i, this)){
A[A.length]= val;
}
}
++i;
}
}
return A;
},
every: function(fun, scope){
var L= this.length, i= 0;
if(typeof fun== 'function'){
while(i<L){
if(i in this && !fun.call(scope, this[i], i, this))
return false;
++i;
}
return true;
}
return null;
},
forEach: function(fun, scope){
var L= this.length, i= 0;
if(typeof fun== 'function'){
while(i< L){
if(i in this){
fun.call(scope, this[i], i, this);
}
++i;
}
}
return this;
},
indexOf: function(what, i){
i= i || 0;
var L= this.length;
while(i< L){
if(this[i]=== what)
return i;
++i;
}
return -1;
},
lastIndexOf: function(what, i){
var L= this.length;
i= i || L-1;
if(isNaN(i) || i>= L)
i= L-1;
else
if(i< 0) i += L;
while(i> -1){
if(this[i]=== what)
return i;
--i;
}
return -1;
},
map: function(fun, scope){
var L= this.length, A= Array(this.length), i= 0, val;
if(typeof fun== 'function'){
while(i< L){
if(i in this){
A[i]= fun.call(scope, this[i], i, this);
}
++i;
}
return A;
}
},
some: function(fun, scope){
var i= 0, L= this.length;
if(typeof fun== 'function'){
while(i<L){
if(i in this && fun.call(scope, this[i], i, this))
return true;
++i;
}
return false;
}
}
}
for(p in p2){
if(!ap[p])
ap[p]= p2[p];
}
return true;
})();
自從我上大學以來,我已經使用 Java、JavaScript、Pascal、 ABAP 、PHP、 Progress 4GL 、C/C++ 以及一些我現在想不出的其他語言進行編程。
雖然它們都有自己的語言特性,但這些語言中的每一種都有許多相同的基本概念。 這些概念包括過程/函數、 IF
語句、 FOR
循環和WHILE
循環。
for
循環傳統for
循環包含三個組件:
這三個組件之間用;
隔開。 象征。 這三個組件中的每一個的內容都是可選的,這意味着以下是盡可能少for
循環:
for (;;) {
// Do stuff
}
當然,您需要包含一個if(condition === true) { break; }
if(condition === true) { break; }
或if(condition === true) { return; }
if(condition === true) { return; }
在那個for
-loop 里面的某個地方讓它停止運行。
但是,通常初始化用於聲明索引,條件用於將該索引與最小值或最大值進行比較,事后考慮用於增加索引:
for (var i = 0, length = 10; i < length; i++) {
console.log(i);
}
for
循環遍歷數組遍歷數組的傳統方法是:
for (var i = 0, length = myArray.length; i < length; i++) {
console.log(myArray[i]);
}
或者,如果您更喜歡向后循環,請執行以下操作:
for (var i = myArray.length - 1; i > -1; i--) {
console.log(myArray[i]);
}
但是,可能有許多變化,例如這個:
for (var key = 0, value = myArray[key], length = myArray.length; key < length; value = myArray[++key]) {
console.log(value);
}
……或者這個……
var i = 0, length = myArray.length;
for (; i < length;) {
console.log(myArray[i]);
i++;
}
...或者這個:
var key = 0, value;
for (; value = myArray[key++];){
console.log(value);
}
哪個效果最好在很大程度上取決於個人品味和您正在實施的特定用例。
請注意,所有瀏覽器都支持這些變體中的每一個,包括非常非常舊的瀏覽器!
while
循環 for
循環的一種替代方法是while
循環。 要遍歷數組,您可以這樣做:
var key = 0;
while(value = myArray[key++]){
console.log(value);
}
與傳統for
循環一樣,即使是最古老的瀏覽器也支持while
循環。
另外,請注意,每個 while 循環都可以重寫為for
循環。 例如,上面的while
循環與for
循環的行為方式完全相同:
for(var key = 0; value = myArray[key++];){
console.log(value);
}
For...in
和for...of
在 JavaScript 中,您也可以這樣做:
for (i in myArray) {
console.log(myArray[i]);
}
然而,這應該小心使用,因為在所有情況下它的行為都與傳統for
循環不同,並且需要考慮潛在的副作用。 請參閱為什么使用“for...in”進行數組迭代是一個壞主意? 更多細節。
作為for...in
的替代方案,現在還有for...of
。 以下示例顯示了for...of
循環和for...in
循環之間的區別:
var myArray = [3, 5, 7];
myArray.foo = "hello";
for (var i in myArray) {
console.log(i); // logs 0, 1, 2, "foo"
}
for (var i of myArray) {
console.log(i); // logs 3, 5, 7
}
此外,您需要考慮沒有任何版本的 Internet Explorer 支持for...of
( Edge 12+支持)並且for...in
至少需要 Internet Explorer 10。
Array.prototype.forEach()
for
循環的替代方法是Array.prototype.forEach()
,它使用以下語法:
myArray.forEach(function(value, key, myArray) {
console.log(value);
});
所有現代瀏覽器以及 Internet Explorer 9 及更高版本都支持Array.prototype.forEach()
。
最后,許多實用程序庫也有自己的foreach
變體。 AFAIK,最受歡迎的三個是:
jQuery.each()
,在jQuery中:
$.each(myArray, function(key, value) {
console.log(value);
});
_.each(myArray, function(value, key, myArray) {
console.log(value);
});
_.forEach()
,在Lodash中:
_.forEach(myArray, function(value, key) {
console.log(value);
});
您可以通過許多不同的方法循環遍歷數組。 我從上到下對我最喜歡的 6 種方法進行了排序。
當它只是簡單地遍歷一個數組時, for
循環是我的首選。
let array = [1, 2, 3, 4, 5]; for (let i = 0; i < array.length; i++) { console.log(array[i]); }
forEach
循環是一種遍歷數組的現代方式。 此外,它提供了更多的靈活性和對數組和元素的控制。
let array = [1, 2, 3, 4, 5]; array.forEach((element) => { console.log(element); });
for...of
循環使您可以直接訪問數組元素。
let array = [1, 2, 3, 4, 5]; for (let element of array) { console.log(element); }
for...in
為您提供一個可以訪問數組元素的鍵。
let array = [1, 2, 3, 4, 5]; for(let index in array){ console.log(array[index]); }
while 循環也可用於遍歷數組。
let array = [1, 2, 3, 4, 5]; let length = array.length; while(length > 0){ console.log(array[array.length - length]); length--; }
同樣,我使用do...while
循環
let array = [1, 2, 3, 4, 5]; let length = array.length; do { console.log(array[array.length - length]); length--; } while (length > 0)
使用while循環...
var i = 0, item, items = ['one', 'two', 'three'];
while(item = items[i++]){
console.log(item);
}
它記錄:“一”、“二”和“三”
而對於相反的順序,一個更有效的循環:
var items = ['one', 'two', 'three'], i = items.length;
while(i--){
console.log(items[i]);
}
它記錄:“三”、“二”和“一”
或者經典for
循環:
var items = ['one', 'two', 'three']
for(var i=0, l = items.length; i < l; i++){
console.log(items[i]);
}
它記錄:'一','二','三'
如果您想要一種簡潔的方式來編寫快速循環,並且可以反向迭代:
for (var i=myArray.length;i--;){
var item=myArray[i];
}
這有緩存長度的好處(類似於for (var i=0, len=myArray.length; i<len; ++i)
而不像for (var i=0; i<myArray.length; ++i)
) 同時輸入的字符更少。
有時您甚至應該反向迭代,例如在迭代活動的 NodeList時,您計划在迭代期間從 DOM 中刪除項目。
在 JavaScript 中以函數式編程方式循環數組的一些用例:
const myArray = [{x:100}, {x:200}, {x:300}];
myArray.forEach((element, index, array) => {
console.log(element.x); // 100, 200, 300
console.log(index); // 0, 1, 2
console.log(array); // same myArray object 3 times
});
注意: Array.prototype.forEach() 嚴格來說不是函數方式,因為它作為輸入參數的函數不應該返回值,因此不能被視為純函數。
const people = [
{name: 'John', age: 23},
{name: 'Andrew', age: 3},
{name: 'Peter', age: 8},
{name: 'Hanna', age: 14},
{name: 'Adam', age: 37}];
const anyAdult = people.some(person => person.age >= 18);
console.log(anyAdult); // true
const myArray = [{x:100}, {x:200}, {x:300}];
const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]
注意: map() 方法創建一個新數組,其結果是在調用數組中的每個元素上調用提供的函數。
const myArray = [{x:100}, {x:200}, {x:300}];
const sum = myArray.map(element => element.x).reduce((a, b) => a + b, 0);
console.log(sum); // 600 = 0 + 100 + 200 + 300
const average = sum / myArray.length;
console.log(average); // 200
const myArray = [{x:100}, {x:200}, {x:300}];
const newArray= myArray.map(element => {
return {
...element,
x: element.x * 2
};
});
console.log(myArray); // [100, 200, 300]
console.log(newArray); // [200, 400, 600]
const people = [
{name: 'John', group: 'A'},
{name: 'Andrew', group: 'C'},
{name: 'Peter', group: 'A'},
{name: 'James', group: 'B'},
{name: 'Hanna', group: 'A'},
{name: 'Adam', group: 'B'}];
const groupInfo = people.reduce((groups, person) => {
const {A = 0, B = 0, C = 0} = groups;
if (person.group === 'A') {
return {...groups, A: A + 1};
} else if (person.group === 'B') {
return {...groups, B: B + 1};
} else {
return {...groups, C: C + 1};
}
}, {});
console.log(groupInfo); // {A: 3, C: 1, B: 2}
const myArray = [{x:100}, {x:200}, {x:300}];
const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}]
注意: filter() 方法創建一個新數組,其中包含通過提供的函數實現的測試的所有元素。
const people = [
{ name: "John", age: 21 },
{ name: "Peter", age: 31 },
{ name: "Andrew", age: 29 },
{ name: "Thomas", age: 25 }
];
let sortByAge = people.sort(function (p1, p2) {
return p1.age - p2.age;
});
console.log(sortByAge);
const people = [ {name: "john", age:23},
{name: "john", age:43},
{name: "jim", age:101},
{name: "bob", age:67} ];
const john = people.find(person => person.name === 'john');
console.log(john);
Array.prototype.find() 方法返回數組中滿足提供的測試函數的第一個元素的值。
是的,你可以在 JavaScript 中使用循環來做同樣的事情,但不限於此。 有很多方法可以在 JavaScript 中對數組進行循環。 假設您在下面有這個數組,並且您想對其進行循環:
var arr = [1, 2, 3, 4, 5];
這些是解決方案:
1)for循環
for
循環是 JavaScript 中遍歷數組的常用方法,但它不被認為是大型數組的最快解決方案:
for (var i=0, l=arr.length; i<l; i++) {
console.log(arr[i]);
}
2)while循環
while 循環被認為是循環長數組的最快方式,但在 JavaScript 代碼中通常較少使用:
let i=0;
while (arr.length>i) {
console.log(arr[i]);
i++;
}
3)做一會兒
do while
while
while 執行相同的操作,但語法差異如下:
let i=0;
do {
console.log(arr[i]);
i++;
}
while (arr.length>i);
這些是執行 JavaScript 循環的主要方法,但還有其他幾種方法可以做到這一點。
我們還使用for in
循環來循環 JavaScript 中的對象。
另請查看 JavaScript 中數組上的map()
、 filter()
、 reduce()
等函數。 他們可能比使用while
和for
更快更好地做事。
如果您想了解更多關於 JavaScript 中數組上的異步函數的信息,這是一篇很好的文章。
這些天來,函數式編程在開發界引起了轟動。 並且有充分的理由:函數式技術可以幫助您編寫更易於一目了然、重構和測試的聲明性代碼。
函數式編程的基石之一是它對列表和列表操作的特殊使用。 而這些東西正是它們聽起來的樣子:一系列的東西,以及你對它們所做的事情。 但是功能性思維方式對待它們的方式與您預期的有所不同。
本文將仔細研究我喜歡稱之為“三巨頭”的列表操作:map、filter 和 reduce。 圍繞這三個函數展開思考是朝着編寫干凈的函數式代碼邁出的重要一步,並為函數式和反應式編程的強大技術打開了大門。
這也意味着您永遠不必再次編寫 for 循環。
在此處閱讀更多>>:
有一種方法可以做到這一點,您的循環中的隱式范圍非常小,並消除了額外的變量。
var i = 0,
item;
// Note this is weak to sparse arrays or falsey values
for ( ; item = myStringArray[i++] ; ){
item; // This is the string at the index.
}
或者,如果您真的想獲得 id 並擁有一個非常經典for
循環:
var i = 0,
len = myStringArray.length; // Cache the length
for ( ; i < len ; i++ ){
myStringArray[i]; // Don't use this if you plan on changing the length of the array
}
現代瀏覽器都支持迭代器方法forEach
、 map
、 reduce
、 filter
和Array 原型上的許多其他方法。
我強烈推薦使用Underscore.js庫。 它為您提供了可用於迭代數組/集合的各種函數。
例如:
_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...
在 JavaScript 中有多種循環遍歷數組的方法。
通用循環:
var i;
for (i = 0; i < substr.length; ++i) {
// Do something with `substr[i]`
}
ES5 的 forEach:
substr.forEach(function(item) {
// Do something with `item`
});
jQuery.每個:
jQuery.each(substr, function(index, item) {
// Do something with `item` (or `this` is also `item` if you like)
});
看看這個以獲取詳細信息,或者您也可以檢查MDN以在 JavaScript 中循環遍歷數組並使用 jQuery 檢查每個 jQuery 。
數組循環:
for(var i = 0; i < things.length; i++){
var thing = things[i];
console.log(thing);
}
對象循環:
for(var prop in obj){
var propValue = obj[prop];
console.log(propValue);
}
如果有人對 Array 迭代可用的多種機制的性能方面感興趣,我准備了以下 JSPerf 測試:
https://jsperf.com/fastest-array-iterator
傳統for()
迭代器是迄今為止最快的方法,尤其是與數組長度 cached一起使用時。
let arr = [1,2,3,4,5];
for(let i=0, size=arr.length; i<size; i++){
// Do something
}
Array.prototype.forEach()
和Array.prototype.map()
方法是最慢的近似值,可能是函數調用開銷的結果。
我還沒有看到這種變化,我個人最喜歡它:
給定一個數組:
var someArray = ["some", "example", "array"];
您可以在不訪問 length 屬性的情況下遍歷它:
for (var i=0, item; item=someArray[i]; i++) {
// item is "some", then "example", then "array"
// i is the index of item in the array
alert("someArray[" + i + "]: " + item);
}
看到這個 JsFiddle 證明:http: //jsfiddle.net/prvzk/
這僅適用於非稀疏數組。 這意味着數組中的每個索引實際上都有一個值。 但是,我發現在實踐中我幾乎從不使用 JavaScript 中的稀疏數組……在這種情況下,將對象用作映射/哈希表通常要容易得多。 如果你確實有一個稀疏數組,並且想要循環 0 .. length-1,你需要 for (var i=0; i<someArray.length; ++i) 構造,但你仍然需要一個if
在循環檢查當前索引處的元素是否實際定義。
此外,正如 CMS 在下面的評論中提到的那樣,您只能在不包含任何虛假值的數組上使用它。 示例中的字符串數組有效,但如果您有空字符串,或者數字為 0 或 NaN 等,則循環將過早中斷。 同樣在實踐中,這對我來說幾乎不是問題,但要牢記這一點,這使得在使用它之前要考慮一個循環......這可能會讓某些人失去資格:)
我喜歡這個循環的地方是:
這樣做的原因是數組規范要求當您從索引中讀取一個 >= 數組長度的項目時,它將返回未定義的。 當您寫入這樣的位置時,它實際上會更新長度。
對我來說,這個結構最接近地模擬了我喜歡的 Java 5 語法:
for (String item : someArray) {
}
...還有一個額外的好處是還知道循環內的當前索引
如果您使用 jQuery 庫,請考慮使用http://api.jquery.com/jQuery.each/
從文檔中:
jQuery.each( collection, callback(indexInArray, valueOfElement) )
返回:對象
描述:一個通用迭代器函數,可用於無縫迭代對象和數組。 具有長度屬性的數組和類數組對象(例如函數的 arguments 對象)通過數字索引進行迭代,從 0 到 length-1。 其他對象通過其命名屬性進行迭代。
$.each()
函數與$(selector).each()
,后者用於以獨占方式迭代 jQuery 對象。$.each()
函數可用於迭代任何集合,無論是映射(JavaScript 對象)還是數組。 在數組的情況下,回調每次都會傳遞一個數組索引和一個對應的數組值。 (該值也可以通過this
關鍵字訪問,但 JavaScript 將始終將this
值包裝為一個Object
,即使它是一個簡單的字符串或數字值。)該方法返回其第一個參數,即被迭代的對象。
數組迭代有4種方式:
// 1: for
for (let i = 0; i < arr.length; ++i) {
console.log(arr[i]);
}
// 2: forEach
arr.forEach((v, i) => console.log(v));
// 3: for in
for (let i in arr) {
console.log(arr[i]);
}
// 4: for of
for (const v of arr) {
console.log(v);
}
摘要:1 和 3 解決方案創建額外的變量,2 - 創建額外的函數上下文。 最好的方法是第 4 - "for of" 。
深奧的可變方式
let a= ["Hello", "World"]; while(a.length) { console.log( a.shift() ); }
有一種方法可以僅迭代自己的對象屬性,不包括原型的屬性:
for (var i in array) if (array.hasOwnProperty(i)) {
// Do something with array[i]
}
但它仍然會遍歷自定義屬性。
在 JavaScript 中,任何自定義屬性都可以分配給任何對象,包括數組。
如果想要遍歷稀疏數組,應該for (var i = 0; i < array.length; i++) if (i in array)
或array.forEach
和es5shim
。
var arr = [1, 2, 3, 1023, 1024];
for (var value; value = arr.pop();) {
value + 1
}
http://jsperf.com/native-loop-performance/8
比較循環遍歷 100000 個項目的數組的方法,並每次對新值進行最小操作。
准備:
<script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<script>
Benchmark.prototype.setup = function() {
// Fake function with minimal action on the value
var tmp = 0;
var process = function(value) {
tmp = value; // Hold a reference to the variable (prevent engine optimisation?)
};
// Declare the test Array
var arr = [];
for (var i = 0; i < 100000; i++)
arr[i] = i;
};
</script>
測試:
<a href="http://jsperf.com/native-loop-performance/16"
title="http://jsperf.com/native-loop-performance/16"
><img src="http://i.imgur.com/YTrO68E.png" title="Hosted by imgur.com" /></a>
優化的方法是緩存數組的長度並使用單變量模式,使用單個var
關鍵字初始化所有變量。
var i, max, myStringArray = ["Hello", "World"];
for (i = 0, max = myStringArray.length; i < max; i++) {
alert(myStringArray[i]);
// Do something
}
如果迭代順序無關緊要,那么您應該嘗試反向循環。 它是最快的,因為它減少了條件測試的開銷,並且減量在一個語句中:
var i,myStringArray = ["item1","item2"];
for (i = myStringArray.length; i--) {
alert(myStringArray[i]);
}
或者更好更干凈地使用while循環:
var myStringArray = ["item1","item2"],i = myStringArray.length;
while(i--) {
// Do something with fruits[i]
}
在 JavaScript 中有幾種方法可以做到這一點。 前兩個示例是 JavaScript 示例。 第三個使用 JavaScript 庫,即 jQuery 使用.each()
函數。
var myStringArray = ["hello", "World"]; for(var i in myStringArray) { alert(myStringArray[i]); }
var myStringArray = ["hello", "World"]; for (var i=0; i < myStringArray.length; i++) { alert(myStringArray[i]); }
var myStringArray = ["hello", "World"]; $.each(myStringArray, function(index, value){ alert(value); })
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
如果你想使用 jQuery,它的文檔中有一個很好的例子:
$.each([ 52, 97 ], function( index, value ) {
alert( index + ": " + value );
});
在 JavaScript 中,有很多方法可以循環數組。
下面的代碼是流行的
/** Declare inputs */ const items = ['Hello', 'World'] /** Solution 1. Simple for */ console.log('solution 1. simple for') for (let i = 0; i < items.length; i++) { console.log(items[i]) } console.log() console.log() /** Solution 2. Simple while */ console.log('solution 2. simple while') let i = 0 while (i < items.length) { console.log(items[i++]) } console.log() console.log() /** Solution 3. forEach*/ console.log('solution 3. forEach') items.forEach(item => { console.log(item) }) console.log() console.log() /** Solution 4. for-of*/ console.log('solution 4. for-of') for (const item of items) { console.log(item) } console.log() console.log()
我認為最好的方法是使用 Array.forEach 函數。 如果您不能使用它,我建議您從 MDN 獲取 polyfill。 為了使其可用,它無疑是在 JavaScript 中迭代數組的最安全方法。
因此,正如其他人所建議的那樣,這幾乎總是您想要的:
var numbers = [1,11,22,33,44,55,66,77,88,99,111];
var sum = 0;
numbers.forEach(function(n){
sum += n;
});
這可確保您在處理數組范圍內所需的任何內容都保持在該范圍內,並且您只處理數組的值,而不是對象屬性和其他成員,這就是for ..
in 所做的。
在大多數情況下,使用常規 C 風格for
循環是可行的。 重要的是要記住循環中的所有內容都與程序的其余部分共享其范圍,{} 不會創建新范圍。
因此:
var sum = 0;
var numbers = [1,11,22,33,44,55,66,77,88,99,111];
for(var i = 0; i<numbers.length; ++i){
sum += numbers[i];
}
alert(i);
將輸出“11” - 這可能是也可能不是你想要的。
一個有效的 jsFiddle 示例: https ://jsfiddle.net/workingClassHacker/pxpv2dh5/7/
它不是 100% 相同,但相似:
var myStringArray = ['Hello', 'World']; // The array uses [] not {} for (var i in myStringArray) { console.log(i + ' -> ' + myStringArray[i]); // i is the index/key, not the item }
例如,我在 Firefox 控制台中使用:
[].forEach.call(document.getElementsByTagName('pre'), function(e){
console.log(e);
})
您可以使用 querySelectorAll 獲得相同的結果
document.querySelectorAll('pre').forEach( (e) => { console.log(e.textContent); })
<pre>text 1</pre> <pre>text 2</pre> <pre>text 3</pre>
正式的(也許是舊的)方式是Array.prototype.forEach(...)
:
var arr = ["apple", "banana", "cherry", "mango"];
arr.forEach(function(item, index, _) {
console.log("[" + index + "] = '" + item + "'");
});
var x = [4, 5, 6];
for (i = 0, j = x[i]; i < x.length; j = x[++i]) {
console.log(i,j);
}
干凈多了...
在Java中,可以使用for
循環遍歷數組中的對象,如下所示:
String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray)
{
// Do something
}
您可以在JavaScript中做同樣的事情嗎?
//Make array
var array = ["1","2","3","4","5","6","7","8","9","10"]
//Loop
for(var i = 0; i < array.length; i++){
console.log((i+1) + " --> " + array[i])
}
對於i
的實際數字,如果需要,您需要將(i+1)
更改為i
或(i)
。
希望這有幫助。
似乎列出了所有變體,除了lodash 的forEach
:
_.forEach([1, 2], (value) => {
console.log(value);
});
只是一個簡單的單線解決方案:
arr = ["table", "chair"]; // Solution arr.map((e) => { console.log(e); return e; });
嗯,這個怎么樣:
for (var key in myStringArray) {
console.log(myStringArray[key]);
}
當然,它效率低下,很多人都鄙視它,但這是最接近上述方法之一:
var myStringArray = ["Hello","World"];
myStringArray.forEach(function(f){
// Do something
})
var myStringArray = ["hello", "World"];
myStringArray.forEach(function(val, index){
console.log(val, index);
})
var obj = ["one","two","three"];
for(x in obj){
console.log(obj[x]);
}
最好使用順序for
循環:
for (var i = 0; i < myStringArray.length; i++) {
// Do something
}
給定一個數組,您可以通過以下多種方式之一遍歷它。
1.經典for
循環
const myArray = ['Hello', 'World']; for (let i = 0; i < myArray.length; i++) { console.log(myArray[i]); }
2. for...of
const myArray = ['Hello', 'World']; for (const item of myArray) { console.log(item); }
const myArray = ['Hello', 'World']; myArray.forEach(item => { console.log(item); });
4. while
循環
const myArray = ['Hello', 'World']; let i = 0; while (i < myArray.length) { console.log(myArray[i]); i++; }
5. do...while
循環
const myArray = ['Hello', 'World']; let i = 0; do { console.log(myArray[i]); i++; } while (i < myArray.length);
6. 隊列樣式
const myArray = ['Hello', 'World']; while (myArray.length) { console.log(myArray.shift()); }
7. 堆疊風格
注意:該列表在此反印。
const myArray = ['Hello', 'World']; while (myArray.length) { console.log(myArray.pop()); }
var array = ['hai', 'hello', 'how', 'are', 'you'] $(document).ready(function () { $('#clickButton').click(function () { for (var i = 0; i < array.length; i++) { alert(array[i]) } }) })
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script> <input id="clickButton" value="click Me" type="button"/> <div id="show"></div>
考慮一下:
var item = ['One','Two','Three'] var item=-1
然后,您會在每次調用時循環:
項目[項目=項目==項目.length-1?0:項目+1]
在 javascript 中有多種方法可以做到這一點。 以下是處理arrays的常用方法。
方法一:
const students = ["Arun","Jos","John","Kiran"]
for (var index = 0; index < students.length; index++) {
console.log(students[index]);
}
方法二:
students.forEach((student, index) => console.log(student));
方法三:
for (const student of students) {
console.log(student);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.