整理一下常用的數(shù)組方法(含ES6)
Array.from(arrayLike[, mapFn[, thisArg]])
將一個類數(shù)組對象或可遍歷對象轉(zhuǎn)換成真正的數(shù)組, 然后就可以在該對象上使用數(shù)組方法
該方法有一個可選參數(shù)mapFn,讓你可以在最后生成的數(shù)組上再執(zhí)行一次 map 方法后再返回。也就是說 Array.from(obj, mapFn, thisArg) 就相當(dāng)于 Array.from(obj).map(mapFn, thisArg)
例子:
Array.from('abc'); // ['a', 'b', 'c']
var a = Array.from(document.querySelectorAll('p'))
Array.isArray(a) // true
(function () {
var args = Array.from(arguments);
return args;
})(1, 2, 3);
// ES6
(function(first, ...rest) {
console.log('first: ', first);
console.log('rest: ', rest);
})(1, 2, 3);
// ES5
(function() {
var first = arguments[0];
var rest = Array.from(arguments).slice(1);
console.log('first: ', first);
console.log('rest: ', rest);
})(1, 2, 3);
// 輸出
// first: 1
// rest: [ 2, 3 ]
Array.from([1, 2, 3], x => x + x); // [2, 4, 6]
Array.isArray()
判斷某個值是否為Array
. 如果是,則返回 true, 否則返回 false
例子:
Array.isArray(new Array()); // true
// 鮮為人知的事實:其實 Array.prototype 也是一個數(shù)組。
Array.isArray(Array.prototype); // true
Polyfill:
if(!Array.isArray){
Array.isArray = function(arg){
return Object.prototype.toString.call(arg) === '[object Array]';
};
}
Array.prototype.concat()
將傳入的數(shù)組或非數(shù)組值與原數(shù)組合并,組成一個新的數(shù)組并返回(不改變原數(shù)組)
let a1 = [1,2];
let a2 = [3,4];
let a3 = [5,6];
a1.concat(a2); // [1, 2, 3, 4]
a1.concat(3,4,5); // [1, 2, 3, 4, 5]
a1.concat(a2, a3); // [1, 2, 3, 4, 5, 6]
Array.prototype.copyWithin(target, start, end)
copyWithin() 方法淺復(fù)制數(shù)組的一部分到同一數(shù)組中的另一個位置,并返回它,而不修改其大小.
例子:
/*
* target: 0 為基底的索引,復(fù)制序列到該位置。如果是負數(shù),target 將從末尾開始計算
* start: 0 為基底的索引,開始復(fù)制元素的起始位置. 如果 start 被忽略,copyWithin 將會從0開始復(fù)制
* end: 0 為基底的索引,開始復(fù)制元素的結(jié)束位置. 如果 end 被忽略,copyWithin 將會復(fù)制到 arr.length
*/
['alpha', 'bravo', 'charlie', 'delta'].copyWithin(2, 0);
// results in ["alpha", "bravo", "alpha", "bravo"]
[].copyWithin.call({length: 5, 3: 1}, 0, 3);
// { 0: 1, 3: 1, length: 5 }
// https://segmentfault.com/q/1010000004571952
Polyfill:
if (!Array.prototype.copyWithin) {
Array.prototype.copyWithin = function(target, start/*, end*/) {
// Steps 1-2.
if (this == null) {
throw new TypeError('this is null or not defined');
}
var O = Object(this);
// Steps 3-5.
var len = O.length >>> 0;
// Steps 6-8.
var relativeTarget = target >> 0;
var to = relativeTarget < 0 ?
Math.max(len + relativeTarget, 0) :
Math.min(relativeTarget, len);
// Steps 9-11.
var relativeStart = start >> 0;
var from = relativeStart < 0 ?
Math.max(len + relativeStart, 0) :
Math.min(relativeStart, len);
// Steps 12-14.
var end = arguments[2];
var relativeEnd = end === undefined ? len : end >> 0;
var final = relativeEnd < 0 ?
Math.max(len + relativeEnd, 0) :
Math.min(relativeEnd, len);
// Step 15.
var count = Math.min(final - from, len - to);
// Steps 16-17.
var direction = 1;
if (from < to && to < (from + count)) {
direction = -1;
from += count - 1;
to += count - 1;
}
// Step 18.
while (count > 0) {
if (from in O) {
O[to] = O[from];
} else {
delete O[to];
}
from += direction;
to += direction;
count--;
}
// Step 19.
return O;
};
}
Array.prototype.every(callback[, thisArg])
測試數(shù)組的所有元素是否都通過了指定函數(shù)的測試(每一項都通過才返回true)
例子:
// 檢測數(shù)組中的所有元素是否都大于 10
// callback被調(diào)用時傳入三個參數(shù):元素值,元素的索引,原數(shù)組
function isBigEnough(element, index, array) {
return (element.value >= 10);
}
var a = [{ value: 12, id: 1 }, { value: 11, id: 2 }]
var b = [{ value: 8, id: 1 }, { value: 11, id: 2 }]
// apassed is true
var apassed = a.every(isBigEnough);
// bpassed is false
var bpassed = b.every(isBigEnough);
Polyfill:
if (!Array.prototype.every)
{
Array.prototype.every = function(fun /*, thisArg */)
{
'use strict';
if (this === void 0 || this === null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== 'function')
throw new TypeError();
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++)
{
if (i in t && !fun.call(thisArg, t[i], i, t))
return false;
}
return true;
};
}
** Array.prototype.some()**
測試數(shù)組中的某些元素是否通過了指定函數(shù)的測試(有一個符合條件的元素立即返回true), 用法同every()
以上兩種方法區(qū)別
every() 每一項都返回true才返回true
some() 只要有一項返回true就返回true
Array.prototype.filter(callback[, thisArg])
用指定的函數(shù)測試所有元素,并創(chuàng)建一個包含所有通過測試的元素的新數(shù)組(篩選出所有滿足條件的)
例子:
下例使用 filter 創(chuàng)建了一個新數(shù)組,該數(shù)組的元素由原數(shù)組中值大于 10 的元素組成
function isBigEnough(element, index, array) {
return element >= 10;
}
// filtered is [12, 130, 44]
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
Polyfill:
if (!Array.prototype.filter)
{
Array.prototype.filter = function(fun /*, thisArg */)
{
"use strict";
if (this === void 0 || this === null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== "function")
throw new TypeError();
var res = [];
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++)
{
if (i in t)
{
var val = t[i];
// NOTE: Technically this should Object.defineProperty at
// the next index, as push can be affected by
// properties on Object.prototype and Array.prototype.
// But that method's new, and collisions should be
// rare, so use the more-compatible alternative.
if (fun.call(thisArg, val, i, t))
res.push(val);
}
}
return res;
};
}
注意:filter()和every(),some()用法相同,返回值不同,filter返回一個新數(shù)組
Array.prototype.includes()
includes() 方法用來判斷一個數(shù)組是否包含一個指定的值,如果是,酌情返回 true或 false
例子:
let a = [{a: 1}, 2, 3];
a.includes(2); // true
a.includes({a: 1}); //false
Polyfill:
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
if (!Array.prototype.includes) {
Object.defineProperty(Array.prototype, 'includes', {
value: function(searchElement, fromIndex) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If len is 0, return false.
if (len === 0) {
return false;
}
// 4. Let n be ? ToInteger(fromIndex).
// (If fromIndex is undefined, this step produces the value 0.)
var n = fromIndex | 0;
// 5. If n ≥ 0, then
// a. Let k be n.
// 6. Else n < 0,
// a. Let k be len + n.
// b. If k < 0, let k be 0.
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
// 7. Repeat, while k < len
while (k < len) {
// a. Let elementK be the result of ? Get(O, ! ToString(k)).
// b. If SameValueZero(searchElement, elementK) is true, return true.
// c. Increase k by 1.
// NOTE: === provides the correct "SameValueZero" comparison needed here.
if (o[k] === searchElement) {
return true;
}
k++;
}
// 8. Return false
return false;
}
});
}
Array.prototype.find()
數(shù)組中某個元素滿足測試條件,find方法對數(shù)組中的每一項元素執(zhí)行一次callback函數(shù),直至有一個callback返回true.當(dāng)找到了這樣一個元素后,該方法會立即返回這個元素的值,否則返回undefined(找到一個滿足條件的即返回該元素)
這個方法返回第一個符合條件元素的值, 用法和上面類似
例子:用對象的屬性查找數(shù)組里的對象
var inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
function findCherries(fruit) {
return fruit.name === 'cherries';
}
// { name: 'cherries', quantity: 5 }
console.log(inventory.find(findCherries));
Array.prototype.findIndex()
用來查找數(shù)組中某指定元素的索引, 如果找不到指定的元素, 則返回 -1
區(qū)別find()方法:findIndex()
方法返回的是滿足條件的元素的索引,而非它的值
Array.prototype.forEach()
forEach()方法讓數(shù)組的每一項都執(zhí)行一次給定的函數(shù),forEach函數(shù)不支持break,不能跳出循環(huán)
例子:
從每個數(shù)組中的元素值中更新一個對象中每個屬性的值
function Counter() {
this.sum = 0;
this.count = 0;
}
Counter.prototype.add = function(array) {
array.forEach(function(entry) {
this.sum += entry;
++this.count;
}, this);
// ^---- Note
};
var obj = new Counter();
obj.add([2, 5, 9]);
// 3
obj.count
// 16
obj.sum
對象復(fù)制函數(shù)
function copy(obj) {
var copy = Object.create(Object.getPrototypeOf(obj));
var propNames = Object.getOwnPropertyNames(obj);
propNames.forEach(function(name) {
var desc = Object.getOwnPropertyDescriptor(obj, name);
Object.defineProperty(copy, name, desc);
});
return copy;
}
var obj1 = { a: 1, b: 2 };
var obj2 = copy(obj1); // obj2 looks like obj1 now
Polyfill:
// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.io/#x15.4.4.18
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(callback, thisArg) {
var T, k;
if (this == null) {
throw new TypeError(' this is null or not defined');
}
// 1. Let O be the result of calling toObject() passing the
// |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get() internal
// method of O with the argument "length".
// 3. Let len be toUint32(lenValue).
var len = O.length >>> 0;
// 4. If isCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function');
}
// 5. If thisArg was supplied, let T be thisArg; else let
// T be undefined.
if (arguments.length > 1) {
T = thisArg;
}
// 6. Let k be 0
k = 0;
// 7. Repeat, while k < len
while (k < len) {
var kValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty
// internal method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (k in O) {
// i. Let kValue be the result of calling the Get internal
// method of O with argument Pk.
kValue = O[k];
// ii. Call the Call internal method of callback with T as
// the this value and argument list containing kValue, k, and O.
callback.call(T, kValue, k, O);
}
// d. Increase k by 1.
k++;
}
// 8. return undefined
};
}
Array.prototype.indexOf()
返回給定元素能找在數(shù)組中找到的第一個索引值,否則返回-1
例子:
var a = [2, 9, 9];
a.indexOf(2); // 0
a.indexOf(7); // -1
if (a.indexOf(7) === -1) {
// element doesn't exist in array
}
Array.prototype.lastIndexOf()
方法返回給定元素能數(shù)組中的最后一個的索引,如果不存在則返回 -1. 從數(shù)組的后面向前查找,從 fromIndex處開始
Array.prototype.join()
將數(shù)組中的所有元素連接成一個字符串,返回字符串,** 不改變原數(shù)組**
例子:
let a = ['Wind', 'Rain', 'Fire'];
a.join();
// 默認為 ","
// 'Wind,Rain,Fire'
a.join("");
// 分隔符 === 空字符串 ""
// "WindRainFire"
a.join("-");
// 分隔符 "-"
// 'Wind-Rain-Fire'
console.log(a);
// ['Wind', 'Rain', 'Fire']
Array.prototype.map(callback[, thisArg])
返回一個由原數(shù)組中的每個元素調(diào)用一個指定方法后的返回值組成的新數(shù)組,不改變原數(shù)組
回調(diào)函數(shù)必須有返回值(return),如果沒有回返回undefined([undefined, undefined, undefined, undefined])
例子:
// 求數(shù)組中每個元素的平方根
var numbers = [1, 4, 9];
// roots的值為[1, 2, 3], numbers的值仍為[1, 4, 9]
var roots = numbers.map(Math.sqrt);
// 反轉(zhuǎn)字符串
var str = '12345';
Array.prototype.map.call(str, function(x) {
return x;
}).reverse().join(''); // '54321'
Array.prototype.pop()
刪除一個數(shù)組中的最后的一個元素,并且返回這個元素, 改變數(shù)組
Array.prototype.push()
添加一個或多個元素到數(shù)組的末尾,并返回數(shù)組新的長度(length 屬性值)
Array.prototype.reduce()
接收一個函數(shù)作為累加器(accumulator),數(shù)組中的每個值(從左到右)開始合并,最終為一個值,不該變原數(shù)組
例子:
/*
* previousValue: 上一次調(diào)用回調(diào)返回的值,或者是提供的初始值(initialValue)
* currentValue: 數(shù)組中當(dāng)前被處理的元素
* index: 當(dāng)前元素在數(shù)組中的索引
* array: 調(diào)用reduce的數(shù)組
*/
[0,1,2,3,4].reduce(function(previousValue, currentValue, index, array){
return previousValue + currentValue;
});
//數(shù)組扁平化
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {
return a.concat(b);
});
// flattened is [0, 1, 2, 3, 4, 5]
//階乘
function factorial (previousValue,currentValue) {
return previousValue*currentValue
}
var a = [1,2,3,4]
a.reduce(factorial) //24
a.reduce(factorial,10) //240
Array.prototype.reduceRight()
接受一個函數(shù)作為累加器(accumulator),讓每個值(從右到左,亦即從尾到頭)縮減為一個值。(與 reduce()的執(zhí)行方向相反)
Array.prototype.reverse()
顛倒數(shù)組中元素的位置(反序),改變原數(shù)組,并返回該數(shù)組的引用
Array.prototype.shift()
刪除數(shù)組的 第一個 元素,并返回這個元素。該方法會改變數(shù)組的長度
Array.prototype.slice(begin,end)
淺復(fù)制(shallow copy)數(shù)組的一部分(從開始到結(jié)束,不包括結(jié)束)到一個新的數(shù)組,并返回這個新數(shù)組,不改變原數(shù)組
例子:
var a = ['a','b','c','d']
//begin(包含) ,end(不包含)
var b = a.slice(1,3) //["b", "c"]
// begin 可選 如果省略從索引0開始
// end 可選 如果省略則一直提取到原數(shù)組末尾
// 將類數(shù)組轉(zhuǎn)化成數(shù)組
var pNodes = Array.prototype.slice.call(documents.getElementsByTagName("p"))
Array.prototype.sort()
數(shù)組的元素做原地的排序,并返回這個數(shù)組。 sort 排序可能是不穩(wěn)定的。默認按照字符串的Unicode碼位點(code point)排序, 會改變數(shù)組
Array.prototype.splice()
用新元素替換舊元素,以此修改數(shù)組的內(nèi)容,返回新數(shù)組, 不改變原數(shù)組
例子:
/*
* start: 從數(shù)組的哪一位開始修改內(nèi)容
* deleteCount: 整數(shù),表示要移除的數(shù)組元素的個數(shù)
* item: 要添加進數(shù)組的元素
*/
// 從第 3 位開始刪除 1 個元素
removed = myFish.splice(3, 1);
// 運算后的myFish:["angel", "clown", "drum", "surgeon"]
// 被刪除元素數(shù)組:["mandarin"]
// 從第 2 位開始刪除 1 個元素,然后插入 "trumpet"
removed = myFish.splice(2, 1, "trumpet");
// 運算后的myFish: ["angel", "clown", "trumpet", "surgeon"]
// 被刪除元素數(shù)組:["drum"]
Array.prototype.toLocaleString()
返回一個字符串表示數(shù)組中的元素。數(shù)組中的元素將使用各自的 toLocaleString方法轉(zhuǎn)成字符串,這些字符串將使用一個特定語言環(huán)境的字符串(例如一個逗號 ",")隔開
Array.prototype.toString()
返回一個字符串,表示指定的數(shù)組及其元素
判斷一個元素是否是數(shù)組
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}
Array.prototype.unshift()
在數(shù)組的開頭添加一個或者多個元素,并返回數(shù)組新的 length 值