- 1. instanceof可以正確的判斷物件的型別,其內部機制是通過判斷物件的原型鏈中是不是能找到型別的prototype。
let a = ['a','b','c','d','e','f']
console.log(a instanceof Array) // true
複製程式碼
- 2. Array.isArray()
let a = ['a','b','c','d''e','f']
Array.isArray(a) // true
複製程式碼
- 3. Object.prototype.toString.call()
let a = ['a','b','c','d''e','f']
Object.prototype.toString.call(a) // [object Array]
複製程式碼
- 4. join() 方法將一個陣列(或類陣列物件)的所有元素連成一個字串並返回這個字串。且不會改變原陣列。預設連線符為“,”
var elements = ['A', 'B', 'C']
console.log(elements.join()) // A,B,C
console.log(elements.join('')) // ABC
console.log(elements.join('-')) // A-B-C
複製程式碼
- 5. reverse() 方法將陣列中元素的位置顛倒。此方法會改變原陣列。
var elements = ['A', 'B', 'C']
elements.reverse()
console.log(elements) // ['C','B','A']
複製程式碼
- 6. sort() 方法用於對陣列排序,並返回陣列。預設的排序順序是根據字串Unicode碼點。此方法會改變原陣列。
var array1 = [1, 30, 4, 21];
array1.sort();
console.log(array1);// [1, 21, 30, 4]
複製程式碼
- 7. concat() 方法用於合併兩個或多個陣列。此方法不會更改現有陣列,而是返回一個新陣列。
var array1 = ['a', 'b', 'c']
var array2 = ['a', 'e', 'f']
console.log(array1.concat(array2)) // ["a", "b", "c", "a", "e", "f"]
複製程式碼
- 8. slice(begin,end) 方法返回一個新陣列,這一物件是一個由 begin和 end(不包括end)決定的原陣列的淺拷貝。原始陣列不會被改變。
var arr = [1, 2, 3, 4, 5]
arr.slice(0) // [1, 2, 3, 4, 5]
arr.slice(1, 2) // [2]
arr.slice(1, 3) // [2, 3]
複製程式碼
- 9. splice() 方法刪除現有元素或新增新元素來修改陣列,並以陣列返回原陣列被修改的內容。
var arr = [1, 3, 4, 5]
arr.splice(1,0,2) // []
console.log(arr) // [1,2,3,4,5]
arr.splice(4,1) // [5]
console.log(arr) // [1,2,3,4]
複製程式碼
- 10. push() 方法將一個或多個元素新增到陣列的末尾,並返回改陣列的新長度。
var arr = [1,3,5,7]
arr.push(8) // [1,3,5,7,8]
複製程式碼
- 11. unshift() 方法將一個或多個元素加到陣列的開頭,並返回該陣列的新長度。
var arr = [1, 2, 3]
console.log(arr.unshift(4, 5)) // 5
console.log(arr) [4, 5, 1, 2, 3]
複製程式碼
- 12. pop() 方法從陣列中刪除最後一個元素,並返回該元素的值。此方法更改陣列的長度。
var arr = [1, 2, 3]
console.log(arr.pop()) // 3
複製程式碼
- 13. shift() 方法從陣列中刪除第一個元素,並返回該元素的值。此方法更改陣列的長度。
var arr = [1, 2, 3]
console.log(arr.shift()) // [2,3]
複製程式碼
- 14. 遍歷
for in
var arr = [1, 2, 3]
for (var i in arr) {
console.log(arr[i])
}
// 1
// 2
// 3
var obj = {a:1; b:2; c:3}
for (var i in arr) {
console.log(obj[i])
}
// 1
// 2
// 3
複製程式碼
for of 迴圈可以使用的範圍包括陣列、Set 和 Map 結構、某些類似陣列的物件等。
const arr = [1, 2, 3];
for(let v of arr) {
console.log(v);
}
// 1
// 2
// 3
複製程式碼
map() 方法建立一個新陣列,其結果是該陣列的每一個元素都呼叫一個提供的函式後返回的結果。map()方法在一定程度上就是為生成新陣列而生的
var arr = [1,2,3]
var mapArr = arr.map(x => x * 3)
console.log(mapArr) // [1,6,9]
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots的值為[1, 2, 3], numbers的值仍為[1, 4, 9]
複製程式碼
forEach() 方法對陣列的每一個元素執行一次提供的函式。
var arr = [1,2,3]
arr.forEach(function(item,index,arr){
console.log(`arr[${index}]=${item}`)
})
// arr[0]=1
// arr[1]=2
// arr[2]=3
複製程式碼
將for迴圈改為forEach
const items = ['item1', 'item2', 'item3']
const copy = []
// for 迴圈
for (let i = 0; i< items.length; i++) {
copy.push(items[i])
}
// forEach
items.forEach(function(item){
copy.push(item)
})
複製程式碼
如果陣列在迭代時被修改了,則其它元素會被跳過
let words = ['one','two','tree','four']
words.forEach(function(word) {
console.log(word)
if (word === 'two') {
words.shift()
}
})
// one
// two
// four
當到達包含值"two"的項時,整個陣列的第一個項被移除了,這導致所有剩下的項上移一個位置。因為元素"four"現在在陣列更新前的位置,"tree"會被跳過。forEach()不會在迭代之前建立陣列的副本。
複製程式碼
對於陣列和可迭代物件的遍歷方法,我們需要從不同的維度進行對比,方法的功能性,方法的應用場景,方法的相容性,方法的效率,方法的返回值以及是是否改變原始陣列。這些方法是如何實現的,並且考慮低版本瀏覽器的相容性。
forEach()與map()
,every()與some()
,filter()與find()、findIndex()
,keys()、values()與entries()
,reduce()與reduceRight()
js遍歷方法
ES5方法:
forEach arr.forEach(fn,thisArg) 返回undefined
map arr.map(fn,thisArg) 返回新陣列
every arr.every(fn,thisArg) 返回true或false,一假即為假
some arr.some(fn,thisArg) 返回true或false,一真即為真
filter arr.filter 返回新陣列
reduce 返回一個值
reduceRight 返回一個值
for-in 迴圈得到key
ES6方法
for-of 用於迴圈陣列,迴圈得到value
find & findIndex arr.find(fn,thisArg),arr.findIndex(fn,thisArg) 返回陣列中第一個滿足條件的元素(元素的索引),如果沒有則返回undefined(或-1)
entries arr.entries() 返回一個陣列迭代器物件
keys arr.keys() 返回一個陣列索引的迭代器
values arr.values() 返回一個陣列迭代器物件,該物件包含陣列中每個索引的值
Symbol.iterator 返回一個陣列迭代器物件 arrSymbol.interator
- 15. filter() 方法建立一個新陣列,此新陣列包含通過所提供函式實現的測試的所有元素。
var arr = [1,2,3]
const result = arr.filter(x => x >1)
console.log(result) // [2,3]
複製程式碼
- 16. some() 方法測試陣列中的某些元素是否通過由提供的函式實現的測試(1真即真)。陣列中的每一個元素執行一次 callback 函式,直到找到一個使得 callback 返回一個“真值”(即可轉換為布林值 true 的值)。如果找到了這樣一個值,some 將會立即返回 true。否則,some 返回 false。
var arr = [1,2,3]
var even = arr.some(x => x > 5) // false
複製程式碼
- 17. every() 方法測試陣列的所有元素是否都通過了指定函式的測試(一假即為假)。
var arr = [1,2,3]
var passed = arr.every(x => x < 5) // true
複製程式碼
- 18. reduce() 方法對累計器和陣列中的每個元素(從左到右)應用一個函式,將其簡化為單個值。accumulator(累加器),currentValue(當前值)。此方法必須傳入兩個引數。
reducer函式接收4個引數:
- 1.Accumulator (acc) (累計器)
- 2.Current Value (cur) (當前值)
- 3.Current Index(idx) (當前索引)
- 4.Source Array(src) (源陣列)
語法
arr.reduce(callback[, initialValue])
複製程式碼
引數:
- callback 執行陣列中每個值的函式,包含四個引數:1.Accumulator (acc) (累計器) 2.Current Value (cur) (當前值) 3.Current Index(idx) (當前索引)(可選) 4.Source Array(src) (源陣列)(可選)
- initialValue (可選) 作為第一次呼叫callback函式時的第一個引數的值。如果沒有提供初始值,則將使用陣列中的第一個元素。在沒有初始值的空陣列上呼叫reduce將報錯。
reduce
為陣列中的每一個元素執行callback函式,不包括陣列中被刪除或從未被賦值的元素。
var arr = [1,2,3,4]
var reducer = arr.reduce((accumulator,currentValue) => accumulator * currentValue) // 24
複製程式碼
陣列求和
var sum = arr.reduce((accumulator,currentValue) => accumulator + currentValue) // 10
複製程式碼
找出陣列中最大值
var max = arr.reduce((accumulator,currentValue) => accumulator > currentValue ? accumulator : currentValue) // 4
複製程式碼
找出陣列中最小值
var min = arr.reduce((accumulator,currentValue) => accumulator < currentValue ? accumulator : currentValue) // 1
複製程式碼
累加物件陣列裡的值
let initialValue = 0
let sum = [{x: 1},{x: 2},{x: 3}].reduce((accumulator, currentValue) => accumulator + currentValue.x), initialValue)
console.log(sum) // 6
複製程式碼
將二維陣列轉化為一維
let flattened = [[0,1],[2,3],[4,5]].reduce((acc,cur) => acc.concat(cur), []) // [0,1,2,3,4,5]
複製程式碼
計算陣列中每個元素出現的次數
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']
let countedNames = names.reduce(function (allNames, name) {
if (name in allNames) {
allNames[name]++;
}
else {
allNames[name] = 1;
}
return allNames;
}, {})
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
複製程式碼
按屬性對object分類
const people = [
{ name: 'Alice', age: 21 },
{ name: 'Max', age: 20 },
{ name: 'Jane', age: 20 }
]
function groupBy (objectArray, property) {
return objectArray.reduce(function (acc, obj) {
let key = obj[property]
if (!acc[key]) {
acc[key] = []
}
acc[key].push(obj)
return acc
},{})
}
let gruupedPeople = groupBy(people, 'age')
// {
// 20: [
// { name: 'Max', age: 20 },
// { name: 'Jane', age: 20 }
// ],
// 21: [{ name: 'Alice', age: 21 }]
// }
複製程式碼
陣列去重
let arr = [1,2,1,2,3,5,4,5,3,4,3,4,4,4,4]
let result = arr.sort().reduce((init, current)=> {
if(init.length===0 || init[init.length-1] !== current) {
init.push(current)
}
return init
},[])
console.log(result) // [1,2,3,4,5]
複製程式碼
按順序執行Promise
/**
* Runs promises from array of functions that can return promises
* in chained manner
*
* @param {array} arr - promise arr
* @return {Object} promise object
*/
function runPromiseInSequence(arr, input) {
return arr.reduce(
(promiseChain, currentFunction) => promiseChain.then(currentFunction),
Promise.resolve(input)
);
}
// promise function 1
function p1(a) {
new Promise(resolve, reject) {
resolve(a * 5)
}
}
// promise function 2
function p2(a) {
return new Promise((resolve, reject) => {
resolve(a * 2);
});
}
// function 3 - will be wrapped in a resolved promise by .then()
function f3(a) {
return a * 3;
}
// promise function 4
function p4(a) {
return new Promise((resolve, reject) => {
resolve(a * 4);
});
}
const promiseArr = [p1, p2, f3, p4];
runPromiseInSequence(promiseArr, 10)
.then(console.log); // 1200
複製程式碼
功能型函式管道
// Building-blocks to use for composition
const double = x => x + x;
const triple = x => 3 * x;
const quadruple = x => 4 * x;
// Function composition enabling pipe functionality
const pipe = (...functions) => input => functions.reduce(
(acc, fn) => fn(acc),
input
);
// Composed functions for multiplication of specific values
const multiply6 = pipe(double, triple);
const multiply9 = pipe(triple, triple);
const multiply16 = pipe(quadruple, quadruple);
const multiply24 = pipe(double, triple, quadruple);
// Usage
multiply6(6); // 36
multiply9(9); // 81
multiply16(16); // 256
multiply24(10); // 240
複製程式碼
Polyfill
if (!Array.prototype.reduce) {
Object.defineProperty(Array.prototype, 'reduce', {
value: function(callback) {
if (this === null) {
throw new TypeError('Array.prototype.reduce ' +
'called on null or undefined' )
}
if (typeof callback !== 'function') {
throw new TypeError( callback +
' is not a function')
}
// 1. Let O be ? ToObject(this value).
var o = Object(this)
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// Steps 3, 4, 5, 6, 7
var k = 0;
var value;
if (arguments.length >= 2) {
value = arguments[1];
} else {
while (k < len && !(k in o)) {
k++;
}
// 3. If len is 0 and initialValue is not present,
// throw a TypeError exception.
if (k >= len) {
throw new TypeError( 'Reduce of empty array ' +
'with no initial value' );
}
value = o[k++];
}
// 8. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kPresent be ? HasProperty(O, Pk).
// c. If kPresent is true, then
// i. Let kValue be ? Get(O, Pk).
// ii. Let accumulator be ? Call(
// callbackfn, undefined,
// « accumulator, kValue, k, O »).
if (k in o) {
value = callback(value, o[k], k, o);
}
// d. Increase k by 1.
k++;
}
// 9. Return accumulator.
return value;
}
})
}
複製程式碼
如果您需要相容不支援Object.defineProperty的JavaScript引擎,那麼最好不要 polyfill Array.prototype方法,因為你無法使其成為不可列舉的。
- 19. reduceRight() 方法接收一個函式作為累加器和陣列的每個值(從右到左)將其減少為單個值。
const arr = [[1,2],[3,4],[5,6]]
const result = arr.recudeRight((accumulator,currentValue) => accumulator.concat(currentValue))
console.log(result) // [5,6,3,4,1,2]
複製程式碼
reduce()與reduceRight()的區別
var a = ['1', '2', '3', '4', '5'];
var left = a.reduce(function(prev, cur) { return prev + cur; });
var right = a.reduceRight(function(prev, cur) { return prev + cur; });
console.log(left); // "12345"
console.log(right); // "54321"
複製程式碼
- 20. 陣列交換
let arr = [1,2,3]
複製程式碼
方法1
建立臨時變數
let temp = arr[0]
arr[0] = arr[2]
arr[2] = temp
複製程式碼
方法2
ES6解構賦值
[arr[0],arr[2]] = [arr[2],arr[0]]
複製程式碼
方法3
splice方法,此方法會以陣列返回原陣列被修改的內容。
arr.splice(2,1, ...arr.splice(0,1, arr[2]))
注:arr.splice(0,1, arr[2]) // [1] 此時陣列為 [3,2,3]
arr.splice(2,1,1) // 陣列交換位置完成 [3,2,1]
複製程式碼