循環
在Javascript中數組循環使用for循環,跟其他的語言非常類似。
//數組循環
var array = [1,2,3,4,5];
for(var i = 0; i < array.length; i++){
console.log(array[i]);
}
//對象循環
var obj = {a:1,b:2,c:3};
for(var i in obj){
console.log(i+':'+obj[i]);
}
迭代
在ES5中新增了幾種迭代方法(forEach, every, filter, map, some)。根據文檔顯示,這些方法都含有兩個參數:
callback
爲數組中每個元素執行的函數,該函數接收三個參數:
currentValue(當前值)
數組中正在處理的當前元素。
index(索引)
數組中正在處理的當前元素的索引。
array
方法正在操作的數組。
thisArg
可選
可選參數。當執行回調 函數時用作
this的
值(參考對象)。
forEach
循環遍歷數組。forEach
方法按升序爲數組中含有效值的每一項執行一次callback
函數,那些已刪除(使用delete
方法等情況)或者未初始化的項將被跳過(但不包括那些值爲 undefined 的項)。
forEach
遍歷的範圍在第一次調用 callback
前就會確定。調用forEach
後添加到數組中的項不會被 callback
訪問到。如果已經存在的值被改變,則傳遞給 callback
的值是 forEach
遍歷到他們那一刻的值。已刪除的項不會被遍歷到。如果已訪問的元素在迭代時被刪除了(例如使用 shift()) ,之後的元素將被跳過 。
forEach()
爲每個數組元素執行callback函數;不像 map() 或者 reduce() ,它總是返回 undefined 值,並且不可鏈式調用。典型用例是在一個鏈的最後執行副作用。
沒有辦法中止或者跳出 forEach 循環,除了拋出一個異常。如果你需要這樣,使用forEach()方法是錯誤的,你可以用一個簡單的循環作爲替代。
簡單使用
下面的代碼會爲每一個數組元素輸出一行記錄:
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
使用thisArg
從每個數組中的元素值中更新一個對象的屬性:
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)
如果數組在迭代時被修改了,則其他元素會被跳過
下面的例子輸出"one", "two", "four"。當到達包含值"two"的項時,整個數組的第一個項被移除了,這導致所有剩下的項上移一個位置。因爲元素 "four"現在在數組更前的位置,"three"會被跳過。 forEach()
不會在迭代之前創建數組的副本。
var words = ["one", "two", "three", "four"];
words.forEach(function(word) {
console.log(word);
if (word === "two") {
words.shift();
}
});
// one
// two
// four
every
測試數組中所有元素是否都通過指定函數的測試,若有一項終止並返回false。
every
方法爲數組中的每個元素執行一次 callback
函數,直到它找到一個使 callback
返回 false(表示可轉換爲布爾值 false 的值)的元素。如果發現了一個這樣的元素,every
方法將會立即返回 false
。否則,callback
爲每一個元素返回 true
,every
就會返回 true
。callback
只會爲那些已經被賦值的索引調用。不會爲那些被刪除或從來沒被賦值的索引調用。
every
不會改變原數組。
every
遍歷的元素範圍在第一次調用 callback
之前就已確定了。在調用 every
之後添加到數組中的元素不會被 callback
訪問到。如果數組中存在的元素被更改,則他們傳入 callback
的值是 every
訪問到他們那一刻的值。那些被刪除的元素或從來未被賦值的元素將不會被訪問到。
every
和數學中的"所有"類似,當所有的元素都符合條件才返回true。另外,空數組也是返回true。(空數組中所有元素都符合給定的條件,注:因爲空數組沒有元素)。
檢測所有數組元素的大小
檢測數組中的所有元素是否都大於 10。
function isBigEnough(element, index, array) {
return (element >= 10);
}
var passed = [12, 5, 8, 130, 44].every(isBigEnough);
// passed is false
passed = [12, 54, 18, 130, 44].every(isBigEnough);
// passed is true
var a = [1, 2, 3,, 4].every (function(value){
console.log(value)
return value
})//1,2,3,4
console.log(a)//true
a = [1, 2, 3, undefined,4].every (function(value){
console.log(value)
return value
})//1,2,3,undefind
console.log(a)//false
filter
使用指定的函數測試所有的元素,創建並返回一個包含所有通過測試的元素的新數組。如果沒有通過測試則返回空數組。
filter
爲數組中的每個元素調用一次 callback
函數,並利用所有使得 callback
返回 true 或等價於 true 的值的元素創建一個新數組。callback
只會在已經賦值的索引上被調用,對於那些已經被刪除或者從未被賦值的索引不會被調用。那些沒有通過 callback
測試的元素會被跳過,不會被包含在新數組中。
filter
不會改變原數組,它返回過濾後的新數組。
filter
遍歷的元素範圍在第一次調用 callback
之前就已經確定了。在調用 filter
之後被添加到數組中的元素不會被 filter
遍歷到。如果已經存在的元素被改變了,則他們傳入 callback
的值是 filter
遍歷到它們那一刻的值。被刪除或從來未被賦值的元素不會被遍歷到。
使用 filter
創建了一個新數組,該數組的元素由原數組中值大於 10 的元素組成。
var a = [1, 2, 3, 7,4].filter(function(value){
return value > 4
})
console.log(a)//[7]
function isBigEnough(element) {
return element >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered is [12, 130, 44]
map
爲數組每一項(不包括通過某些方法刪除或者未定義的項,值定義爲undefined的項除外)執行一個指定函數,返回一個新數組,每個元素都是回調函數的結果。
map
方法會給原數組中的每個元素都按順序調用一次 callback
函數。callback
每次執行後的返回值(包括 undefined )組合起來形成一個新數組。 callback
函數只會在有值的索引上被調用;那些從來沒被賦過值或者使用 delete
刪除的索引則不會被調用。
map
不修改調用它的原數組本身(當然可以在 callback
執行時改變原數組)。
使用 map 方法處理數組時,數組元素的範圍是在 callback 方法第一次調用之前就已經確定了。在 map 方法執行的過程中:原數組中新增加的元素將不會被 callback 訪問到;若已經存在的元素被改變或刪除了,則它們的傳遞到 callback 的值是 map 方法遍歷到它們的那一時刻的值;而被刪除的元素將不會被訪問到。
下面的代碼創建了一個新數組,值爲原數組中對應數字的平方根:
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots的值爲[1, 2, 3], numbers的值仍爲[1, 4, 9]
使用 map 重新格式化數組中的對象
以下代碼將一個包含對象的數組用以創建一個包含新重新格式化對象的新數組。
var kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
var reformattedArray = kvArray.map(function(obj) {
var rObj = {};
rObj[obj.key] = obj.value;
return rObj;
});
// reformattedArray 數組爲: [{1: 10}, {2: 20}, {3: 30}],
// kvArray 數組未被修改:
// [{key: 1, value: 10},
// {key: 2, value: 20},
// {key: 3, value: 30}]
some
測試數組中某些元素是否通過指定函數的測試,若有一項終止循環返回true。
some
爲數組中的每一個元素執行一次 callback
函數,直到找到一個使得 callback 返回一個“真值”(即可轉換爲布爾值 true 的值)。如果找到了這樣一個值,some
將會立即返回 true
。否則,some
返回 false
。callback
只會在那些”有值“的索引上被調用,不會在那些被刪除或從來未被賦值的索引上調用。
some
被調用時不會改變數組。
some
遍歷的元素的範圍在第一次調用 callback
. 時就已經確定了。在調用 some
後被添加到數組中的值不會被 callback
訪問到。如果數組中存在且還未被訪問到的元素被 callback
改變了,則其傳遞給 callback
的值是 some
訪問到它那一刻的值。
測試數組元素的值
下面的例子檢測在數組中是否有元素大於 10。
function isBiggerThan10(element, index, array) {
return element > 10;
}
[2, 5, 8, 1, 4].some(isBiggerThan10); // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true
使用箭頭函數測試數組元素的值
[2, 5, 8, 1, 4].some(x => x > 10); // false
[12, 5, 8, 1, 4].some(x => x > 10); // true
判斷數組元素中是否存在某個值
var fruits = ['apple', 'banana', 'mango', 'guava'];
function checkAvailability(arr, val) {
return arr.some(function(arrVal) {
return val === arrVal;
});
}
checkAvailability(fruits, 'kela'); // false
checkAvailability(fruits, 'banana'); // true
將任意值轉換爲布爾類型
var TRUTHY_VALUES = [true, 'true', 1];
function getBoolean(value) {
'use strict';
if (typeof value === 'string') {
value = value.toLowerCase().trim();
}
return TRUTHY_VALUES.some(function(t) {
return t === value;
});
}
getBoolean(false); // false
getBoolean('false'); // false
getBoolean(1); // true
getBoolean('true'); // true