全面認(rèn)識(shí)JavaScript的Array對(duì)象
首先一個(gè)是對(duì)JavaScript中Array的理解:JavaScript中函數(shù)是一等公民,寫在代碼中的 Array/Object/String/Number/Function其實(shí)都是一個(gè)構(gòu)造函數(shù),是用來(lái)生成相應(yīng)的數(shù)據(jù)類型的變量的。
數(shù)組描述:數(shù)組是一種類列表對(duì)象,JS數(shù)組的長(zhǎng)度和元素類型都是非固定的。因?yàn)閿?shù)組的長(zhǎng)度可隨時(shí)改變,并且其數(shù)據(jù)在內(nèi)存中也可以不連續(xù),所以JavaScript數(shù)組不一定是密集型的,這取決于它的使用方式。
只能用整數(shù)作為數(shù)組元素的索引,而不能使用字符串。使用非整數(shù)并通過(guò)方口號(hào)或點(diǎn)號(hào)來(lái)訪問(wèn)或設(shè)置數(shù)組元素時(shí),所操作的并不是數(shù)組列表中的元素,而是數(shù)組對(duì)象的屬性集合上的變量。數(shù)組對(duì)象的屬性和數(shù)組元素列表是分開(kāi)存儲(chǔ)的,并且數(shù)組的遍歷和修改操作也不能作用于這些命名屬性。
幾點(diǎn)注意事項(xiàng)
1、雖然數(shù)組可以看做是數(shù)組對(duì)象的屬性,但是不能用點(diǎn)號(hào)引用數(shù)組元素,因?yàn)樵贘avaScript中,以數(shù)字開(kāi)頭的屬性不能用點(diǎn)號(hào)引用,必須用方括號(hào)。
console.log(years.0);//錯(cuò)誤
console.log(years[0]);//正確
//假如render對(duì)象中有一個(gè)名為3d的屬性
render.3d//錯(cuò)誤
render['3d']//正確,引號(hào)是必須的
示例:arr[2]這樣的可以寫成arr['2']。arr[2]中的2會(huì)被JavaScript解釋器通過(guò)調(diào)用toString隱式地轉(zhuǎn)換成字符串。所以arr['2']和arr['02']在arr中引用的可能不是同一個(gè)位置上的元素,而arr[2]和arr[02]訪問(wèn)的是同一個(gè)位置上的元素。下面是一個(gè)示例圖:

2、使用一個(gè)合法的下標(biāo)為數(shù)組元素賦值,如果該下標(biāo)超出了當(dāng)前數(shù)組的大小,解釋器會(huì)同時(shí)修改length的值??梢允謩?dòng)為length賦值,賦值小于當(dāng)前數(shù)組元素個(gè)數(shù)的時(shí)候會(huì)刪除一部分元素。

========== 屬性 ==========
1、length:length是Array的實(shí)例屬性。返回或設(shè)置一個(gè)數(shù)組中的元素個(gè)數(shù)。該值是一個(gè)無(wú)符號(hào)32-bit整數(shù)(0到2^32-1),并且總是大于數(shù)組最高項(xiàng)的下標(biāo)。
2、prototype:前面說(shuō)到Array在代碼中是一個(gè)函數(shù),也就是數(shù)組對(duì)象的構(gòu)造函數(shù),所以它有自己的原型,也就是prototype。Array實(shí)例繼承自Array.prototype。與所有構(gòu)造函數(shù)一樣,我們可以更改構(gòu)造函數(shù)的原型對(duì)象,以對(duì)所有Array實(shí)例進(jìn)行更改。Array.prototype本身也是一個(gè)Array
========= 方法 ==========
1、Array.from(),從一個(gè)類似數(shù)組或可迭代對(duì)象中創(chuàng)建一個(gè)新的數(shù)組實(shí)例。
語(yǔ)法:
Array.from(arrayLike[,mapFn,[,thisArg]]);
//參數(shù)
arrayLike //想要轉(zhuǎn)換成數(shù)組的偽數(shù)組對(duì)象或可迭代對(duì)象。
//偽數(shù)組對(duì)象:擁有一個(gè)length屬性和若干索引屬性的任意對(duì)象
//可迭代對(duì)象:可以獲取對(duì)象中的元素,如Map和Set等
mapFn //如果指定了該參數(shù),新數(shù)組中的每個(gè)元素會(huì)執(zhí)行一遍該回調(diào)函數(shù)
thisArg //執(zhí)行回調(diào)函數(shù)mapFn時(shí)this對(duì)象
//返回值:一個(gè)新的數(shù)組實(shí)例
示例:
Array.from('foo');//['f','o','o']
Array.from(new Set(['foo',window]));//['foo',window]
Array.from(new Map([[1,2],[2,4],[4,8]]));//[[1,2],[2,4],[4,8]]
function f(){
console.log(Array.isArray(arguments)); //false
return Array.from(arguments,function(val,index){
console.log(val);//1,2,3
console.log(index);//0,1,2
return val++
});
}
f(1,2,3); // 2,3,4
注:Array.from()本身是淺拷貝,如果數(shù)組的某個(gè)元素是對(duì)象或數(shù)組等,拷貝過(guò)去的是一個(gè)指向。
2、Array.isArray(),用于確定傳遞的值是否是一個(gè)Array。
語(yǔ)法:
Array.isArray(obj);
// 參數(shù)
obj //需要檢測(cè)的值
// 返回值:如果對(duì)象是Array,則為true;否則為false
// 當(dāng)檢測(cè)Array實(shí)例時(shí), Array.isArray 優(yōu)于 instanceof,因?yàn)锳rray.isArray能檢測(cè)iframes.
let iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]
Array.isArray(arr);//true
arr instanceof Array;//false
3、Array.of(),創(chuàng)建一個(gè)具有可變數(shù)量參數(shù)的新數(shù)組實(shí)例,而不考慮參數(shù)的數(shù)量和類型。
語(yǔ)法:
Array.of(element0[, element1[, ...[, elementN]]])
// 參數(shù)
elementN //任意個(gè)參數(shù),將按順序成為返回?cái)?shù)組中的元素
// 返回值:新的Array實(shí)例
Array.of(7);//[7]
Array.of(1,2,3);//[1,2,3]
Array(7); //[,,,,,,]
Array(1,2,3);//[1,2,3]
========= 實(shí)例方法 =========
這些方法可以直接在數(shù)組實(shí)例上使用,故整理為幾個(gè)大類(自建,無(wú)任何官方說(shuō)明)。
第一類,增刪改查:push/pop/shift/unshift/splice/slice/concat/copyWithin/fill。
1.push(),將一個(gè)或多個(gè)元素添加到數(shù)組的末尾,并返回該數(shù)組的新長(zhǎng)度。
語(yǔ)法
arr.push(element1,...,elementN);
// 參數(shù)
elementN //被添加到數(shù)組末尾的元素
// 返回值:當(dāng)調(diào)用該方法時(shí),新的length屬性值將被返回
push 方法有意具有通用性。該方法和 call() 或 apply() 一起使用時(shí),可應(yīng)用在類似數(shù)組的對(duì)象上。push 方法根據(jù) length 屬性來(lái)決定從哪里開(kāi)始插入給定的值。如果 length 不能被轉(zhuǎn)成一個(gè)數(shù)值,則插入的元素索引為 0,包括 length 不存在時(shí)。當(dāng) length 不存在時(shí),將會(huì)創(chuàng)建它。
示例一:合并兩個(gè)數(shù)組
let arr = [1,2];
let arr1 = [3,4];
Array.prototype.push.apply(arr,arr1);//相當(dāng)于:arr.push(3,4);
console.log(arr);//[1,2,3,4]
//注意第二個(gè)數(shù)組太大時(shí)不要使用該方法,應(yīng)為一個(gè)函數(shù)能夠接受的參數(shù)個(gè)數(shù)是有限制的。
示例二:像數(shù)組一樣使用對(duì)象
let obj = {
length : 0,
addElem: function addElem(elem){
[].push.call(this,elem);
}
};
obj.addElem({});
obj.addElem({});
console.log(obj);
// 盡管 obj 不是數(shù)組,但是 push 方法成功地使 obj 的 length 屬性增長(zhǎng)了,就像我們處理一個(gè)實(shí)際的數(shù)組一樣

2.unshift(),將一個(gè)或多個(gè)元素添加到數(shù)組的開(kāi)頭,并返回該數(shù)組的新長(zhǎng)度。
語(yǔ)法:
arr.unshift(element1,...,elementN);
// 參數(shù)
elementN //要添加到數(shù)組開(kāi)頭的元素
// 返回值:當(dāng)一個(gè)對(duì)象調(diào)用該方法時(shí),返回其length屬性值。
unshift 特意被設(shè)計(jì)成具有通用性;這個(gè)方法能夠通過(guò) call 或 apply 方法作用于類數(shù)組對(duì)象上。不過(guò)對(duì)于沒(méi)有 length 屬性(代表從0開(kāi)始的一系列連續(xù)的數(shù)字屬性的最后一個(gè))的對(duì)象,調(diào)用該方法可能沒(méi)有任何意義。
上面push的示例一和示例二都適用于unshift,只是參數(shù)放在數(shù)組前插入。
3.shift(),從數(shù)組中刪除第一個(gè)元素,并返回該元素的值。
語(yǔ)法:
arr.shift();
// 返回值:從數(shù)組中刪除的元素;如果數(shù)組為空則返回undefined。
shift方法移除索引為0的元素(即第一個(gè)元素),并返回被移除的元素,其他元素的索引值隨之減一。如果length屬性的值為0(長(zhǎng)度為0),則返回undefined。
shift方法并不局限于數(shù)組:這個(gè)方法能夠通過(guò) call 或 apply 方法作用于類似數(shù)組的對(duì)象上。但是對(duì)于沒(méi)有 length 屬性(從0開(kāi)始的一系列連續(xù)的數(shù)字屬性的最后一個(gè))的對(duì)象,調(diào)用該方法可能沒(méi)有任何意義。
4.pop(),刪除數(shù)組中的最后一個(gè)元素,并返回該元素的值。
語(yǔ)法:
arr.pop();
// 返回值:從數(shù)組中刪除的元素(當(dāng)數(shù)組為空時(shí)返回undefined)。
pop 方法從一個(gè)數(shù)組中刪除并返回最后一個(gè)元素。
pop 方法有意具有通用性。該方法和 call() 或 apply() 一起使用時(shí),可應(yīng)用在類似數(shù)組的對(duì)象上。pop方法根據(jù) length屬性來(lái)確定最后一個(gè)元素的位置。如果不包含length屬性或length屬性不能被轉(zhuǎn)成一個(gè)數(shù)值,會(huì)將length置為0,并返回undefined。
5.slice(),返回一個(gè)新的數(shù)組對(duì)象,這個(gè)對(duì)象是一個(gè)由begin和end(不包含end)決定的的原數(shù)組的淺拷貝。原始數(shù)組不會(huì)被改變。
語(yǔ)法:
arr.slice(begin,end);
// 參數(shù)
begin //可選,如果省略begin,則從0開(kāi)始提取。如果該參數(shù)為負(fù)數(shù),則表示從原數(shù)組中的倒數(shù)第幾個(gè)元素開(kāi)始提取。
end // 可選,如果省略end,則slice會(huì)一直提取到原數(shù)組末尾。如果該參數(shù)為負(fù)數(shù),則它表示在原數(shù)組中的倒數(shù)第幾個(gè)元素結(jié)束抽取。
// 返回值:一個(gè)含有提取元素的新數(shù)組
描述:slice不修改原數(shù)組,只會(huì)返回一個(gè)淺復(fù)制了原數(shù)組中的元素的一個(gè)新數(shù)組。原數(shù)組的元素會(huì)按照下述規(guī)則拷貝(即淺拷貝):
- 如果該元素是個(gè)對(duì)象引用(不是實(shí)際的對(duì)象),slice會(huì)拷貝這個(gè)對(duì)象引用到新的數(shù)組里。兩個(gè)對(duì)象引用都引用了同一個(gè)對(duì)象。如果被引用的對(duì)象發(fā)生改變,則新的和原來(lái)的數(shù)組中的這個(gè)元素也會(huì)發(fā)生改變。
- 對(duì)于字符串、數(shù)字及布爾值來(lái)說(shuō)(不是 String、Number 或者 Boolean 對(duì)象),slice 會(huì)拷貝這些值到新的數(shù)組里。在別的數(shù)組里修改這些字符串或數(shù)字或是布爾值,將不會(huì)影響另一個(gè)數(shù)組。
示例一:返回現(xiàn)有數(shù)組的一部分
let fruits = ['Banana','Orange','Lemon','Apple','Mango'];
let citrus = fruits.slice(1,3);
console.log(citrus);//['Orange','Lemon']
console.log(fruits);//['Banana','Orange','Lemon','Apple','Mango']
示例二:類數(shù)組對(duì)象
function list(){
return Array.prototype.slice.call(arguments,0,2);
}
let list1 = list(1,2,3);
console.log(list1);//[1,2]
6.splice(),方法通過(guò)刪除現(xiàn)有元素和/或添加新元素來(lái)修改數(shù)組,并以數(shù)組返回原數(shù)組中被修改的內(nèi)容。
語(yǔ)法:
array.splice(start,[,deleteCount[,item1[,item2[,...]]]]);
// 參數(shù)
start //指定修改的開(kāi)始位置(從0計(jì)數(shù)),刪除的時(shí)候包含該下標(biāo)元素。
// ① 如果超出了數(shù)組的長(zhǎng)度,則從數(shù)組末尾開(kāi)始添加內(nèi)容
// ② 如果是負(fù)值,則表示從數(shù)組末位開(kāi)始的第幾位(從-1計(jì)數(shù))
// ③ 如果負(fù)數(shù)的絕對(duì)值大于數(shù)組的長(zhǎng)度,則表示開(kāi)始位置為第0位
deleteCount //可選,整數(shù),表示要移除的數(shù)組元素的個(gè)數(shù)。
// ① 如果deleteCount是0或者負(fù)數(shù),則不移除元素。這中情況下,至少應(yīng)該添加一個(gè)元素
// ② 如果deleteCount大于start之后的元素的總數(shù),則從start后面的元素都將被刪除(含第start位)
// ③ 如果deleteCount被省略,則其相當(dāng)于(arr.length-start)
item1,item2,... //可選,要添加進(jìn)數(shù)組的元素,從start位置開(kāi)始。如果不指定,則splice()將只刪除數(shù)組元素。
// splice方法使用deleteCount參數(shù)來(lái)控制是刪除還是添加:
// start參數(shù)是必須的,表示開(kāi)始的位置(從0計(jì)數(shù)),如:start=0從第一個(gè)開(kāi)始;start>=array.length-1表示從最后一個(gè)開(kāi)始。
// ① 從start位置開(kāi)始刪除[start,end]的元素
arr.splice(start);
// ② 從start位置開(kāi)始刪除[start,count]的元素
arr.splice(start,deleteCount);
// ③ 從start位置開(kāi)始添加item1,item2,...元素
arr.splice(start,0,item1,item2,...);
// 返回值:由被刪除的元素組成的一個(gè)數(shù)組。如果只刪除了一個(gè)元素,則返回只包含一個(gè)元素的數(shù)組。如果沒(méi)有刪除元素,則返回空數(shù)組。
// 如果添加進(jìn)數(shù)組的元素個(gè)數(shù)不等于被刪除的元素個(gè)數(shù),數(shù)組的長(zhǎng)度會(huì)發(fā)生相應(yīng)的改變。
示例
let myFish = ['angel','clown','mandarin','surgeon'];
let removed = myFish.splice(2,0,'drum');
console.log(myFish);//["angel", "clown", "drum", "mandarin", "surgeon"]
console.log(removed);//[]
let replaced = myFish.splice(2,1,'hahha');
console.log(myFish);// ["angel", "clown", "hahha", "mandarin", "surgeon"]
console.log(replaced);//["drum"]
let deleted = myFish.splice(-1,1);//相當(dāng)于 myFish.splice(myFish.length-1,1);
console.log(myFish);//["angel", "clown", "hahha", "mandarin"]
console.log(deleted);//["surgeon"]
let one = myFish.splice(1);
console.log(myFish);//["angel"],可以看出下標(biāo)為1的元素也被刪除
console.log(one);//["clown", "hahha", "mandarin"]
7.concat(),方法用于合并兩個(gè)或多個(gè)數(shù)組。此方法不會(huì)改變現(xiàn)有數(shù)組,而是返回一個(gè)新數(shù)組。
語(yǔ)法:
let new_array = old_array.concat(value1[,value2[,value3[,...[,valueN]]]]);
// 參數(shù)
valueN //將數(shù)組和/或值連接成新數(shù)組。
// 返回值:新的Array實(shí)例
concat方法創(chuàng)建一個(gè)新的數(shù)組,它由被調(diào)用的對(duì)象中的元素組成,每個(gè)參數(shù)的順序依次是該參數(shù)的元素或元素本身。它不會(huì)遞歸到嵌套數(shù)組參數(shù)中。
concat方法不會(huì)改變this或任何作為參數(shù)提供的數(shù)組,而是返回一個(gè)淺拷貝(參考slice中的描述)。
示例:
let num1= [1,2,3],
num2= ['a','b','c'];
let nums = num1.concat('hah',num2);
console.log(num1);//[1, 2, 3]
console.log(num2);//["a", "b", "c"]
console.log(nums);//[1, 2, 3, "hah", "a", "b", "c"]
let num3 = ['yao',['peng','kun']];
let res = num1.concat(num2,num3);
console.log(num3);//["yao", ["peng","kun"]],標(biāo)記一
console.log(res);//[1, 2, 3, "a", "b", "c", "yao", ["peng","kun"]]
res[7][0]="666";
console.log(num3);//["yao", ["666","kun"]]
console.log(res);//[1, 2, 3, "a", "b", "c", "yao", ["666","kun"]]
// 這里有個(gè)奇怪的現(xiàn)象,當(dāng)我們沒(méi)有寫res[7][0]="666";的時(shí)候,“標(biāo)記一”處顯示的是["yao",Array(2)];點(diǎn)開(kāi)array(2)里面是["peng","kun"],而如果我們?cè)诤竺嫘薷牧耍俅吸c(diǎn)開(kāi)“標(biāo)記一”處console出的Array(2)顯示的是["666","kun"]。
// 個(gè)人猜測(cè):控制臺(tái)中打印的東西,如果需要通過(guò)點(diǎn)擊再顯示出來(lái)的,會(huì)在點(diǎn)擊的時(shí)刻去內(nèi)存中獲取,所以指向型的數(shù)據(jù),后面修改會(huì)影響上面的打印結(jié)果。(可以通過(guò)轉(zhuǎn)為string避免這樣的地址指向即時(shí)獲取,如:console.log(JSON.stringify(num3)))
8.copyWithin(),方法淺復(fù)制數(shù)組的一部分到同一數(shù)組中的另一個(gè)位置,并返回它,而不修改其大小。
語(yǔ)法:
arr.copyWithin(target[,start[,end]]);
// 參數(shù)
target //0為基底的索引,復(fù)制序列到該位置。如果是負(fù)數(shù),target將從末尾開(kāi)始計(jì)算。
// 如果target大于等于arr.length,將會(huì)不發(fā)生拷貝。如果target在start之后,復(fù)制的序列將被修改以符合arr.length。
start //0為基底的索引,開(kāi)始復(fù)制元素的起始位置。如果是負(fù)數(shù),start將從末尾開(kāi)始計(jì)算。
// 如果start被忽略,copyWithin將會(huì)從0開(kāi)始復(fù)制
end // 0為基底的索引,開(kāi)始復(fù)制元素的結(jié)束位置。copyWithin將會(huì)拷貝到該位置,但不包括end這個(gè)位置的元素。如果是負(fù)數(shù),end將從末尾開(kāi)始計(jì)算。
// 如果end被忽略,copyWithin將會(huì)復(fù)制到arr.length。
//返回值:改變了的數(shù)組
參數(shù)target,start,end必須為正數(shù)。
copyWithin方法不要求其this值必須是一個(gè)數(shù)組對(duì)象;除此之外,copyWithin是一個(gè)可變方法,它可以改變this對(duì)象本身,并且返回它,而不僅僅是它的拷貝。
copyWithin函數(shù)的設(shè)計(jì)為通用的,其不要求其this值必須是一個(gè)數(shù)組對(duì)象。
示例:
[1,2,3,4,5].copyWithin(-2);//[1,2,3,1,2]
[1,2,3,4,5].copyWithin(0,3);//[4,5,3,4,5]
[1,2,3,4,5].copyWithin(0,3,4);//[4,2,3,4,5]
[1,2,3,4,5].copyWithin(-2,-3,-1);//[1,2,3,3,4]
[].copyWithin.call({length:5,3:1},0,3);//{0:1,3:1,length:5}
9.fill(),方法用一個(gè)固定值填充一個(gè)數(shù)組中從起始索引到終止索引內(nèi)的全部元素。不包括終止索引。
語(yǔ)法:
arr.fill(value[,start[,end]]);
// 參數(shù)
value // 用來(lái)填充數(shù)組元素的值,為對(duì)象時(shí)填充的是對(duì)象的引用
start // 可選,起始索引,默認(rèn)值為0
end //可選,終止索引,默認(rèn)值為this.length
//start和end都可以是負(fù)數(shù),計(jì)算方法均為:length+start/end
// 返回值:修改后的數(shù)組
fill方法故意設(shè)計(jì)為通用方法,該方法不要求this是數(shù)組對(duì)象
示例:
[1,2,3].fill(4);//[4,4,4]
[1,2,3].fill(4,1);//[1,4,4]
[1,2,3].fill(4,1,2);//[1,4,3]
[1,2,3].fill(4,1,1);//[1,2,3]
[1, 2, 3].fill(4, 3, 3);// [1, 2, 3]
[1, 2, 3].fill(4, -3, -2);// [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN); // [1, 2, 3]
[1, 2, 3].fill(4, 3, 5);// [1, 2, 3]
Array(3).fill(4);// [4, 4, 4]
Array(3).fill(4,1);// [empty, 4, 4]
[].fill.call({ length: 3 }, 4); // {0: 4, 1: 4, 2: 4, length: 3}
[].fill.call({ length: 3 }, 4,1); // {1: 4, 2: 4, length: 3}
let obj = {};
let arr = Array(3).fill(obj);
arr[0].hi='hi';
console.log(arr);//[{hi:'hi'},{hi:'hi'},{hi:'hi'}]
第二類,遍歷數(shù)組
1. forEach/map/filter/every/some/find/findIndex 這七個(gè)方法有相似的語(yǔ)法:
//fn表示“forEach/map/filter/every/some/find/findIndex”中的任意一個(gè)
arr.fn(function callback(currentValue[,index[,array]]){
//執(zhí)行一些操作,并返回一個(gè)值
}[,thisArg]);
// 參數(shù)
callback // 生成新數(shù)組元素的函數(shù),使用三個(gè)參數(shù):
currentValue // 數(shù)組中正在處理的當(dāng)前元素的值
index // 可選,數(shù)組中正在處理的當(dāng)前元素的索引
array // 可選,fn方法被調(diào)用的數(shù)組
thisArg //可選,執(zhí)行callback函數(shù)時(shí)使用的this值
// 如果 thisArg 參數(shù)有值,則每次 callback 函數(shù)被調(diào)用的時(shí)候,this 都會(huì)指向 thisArg 參數(shù)上的這個(gè)對(duì)象。
// 如果省略了 thisArg 參數(shù),或者賦值為 null 或 undefined,則 this 指向全局對(duì)象 。
// callback 函數(shù)最終可觀察到 this 值,這取決于函數(shù)觀察到 this 的常用規(guī)則。
// 如果callback是箭頭函數(shù),則thisArg參數(shù)無(wú)效
下面是幾點(diǎn)需要格外注意的點(diǎn):
- ① 這七個(gè)方法不修改調(diào)用它的原數(shù)組本身(當(dāng)然可以在callback執(zhí)行時(shí)改變?cè)瓟?shù)組)。
- ② 使用這七個(gè)方法處理數(shù)組時(shí),數(shù)組元素的范圍是在callback方法第一次調(diào)用之前就已經(jīng)確定了。在方法執(zhí)行的過(guò)程中:原數(shù)組中新增加的元素將不會(huì)被 callback 訪問(wèn)到;若已經(jīng)存在的元素被改變或刪除了,則它們的傳遞到 callback 的值是方法遍歷到它們的那一時(shí)刻的值;如果已訪問(wèn)的元素在迭代時(shí)被刪除了(例如使用 shift()),某個(gè)元素將被跳過(guò)。即這些方法不會(huì)在調(diào)用之前創(chuàng)建數(shù)組的副本。
- ③ forEach/map/filter/every/some在執(zhí)行過(guò)程中,那些已刪除或者未初始化的項(xiàng)將被跳過(guò)(例如在稀疏數(shù)組上),而find/findIndex在執(zhí)行過(guò)程中會(huì)調(diào)用每個(gè)索引,而不僅僅是那些被賦值的索引,這意味著對(duì)于稀疏數(shù)組來(lái)說(shuō),這兩個(gè)方法的效率要低。
- ④ forEach/map/filter/every/some對(duì)于被刪除的元素將不會(huì)被訪問(wèn)到,而find/findIndex仍舊會(huì)被訪問(wèn)到被刪除的元素
forEach(),按升序?yàn)閿?shù)組中含有有效值的每一項(xiàng)執(zhí)行一次callback函數(shù)。
forEach(),沒(méi)有辦法終止或者跳出循環(huán),除非拋出一個(gè)異常(這種使用方法明顯是錯(cuò)誤的)。如果需要提前終止循環(huán)可以使用:簡(jiǎn)單循環(huán)、for...of、every、some、find、findIndex。
示例:
function logArrayElements(element,index,array){
console.log('a['+index+']='+element);
}
let arr=[2,3,,null,undefined,9];
arr.length=10;
arr.forEach(logArrayElements);
console.log(arr);
結(jié)果:可以看到索引2被跳過(guò)了,null/undefined還是會(huì)被遍歷,多余的empty也不會(huì)被遍歷

示例:使用thisArg
function Counter(){
this.sum = 0;
this.count = 0;
}
Counter.prototype.add = function(array){
array.forEach(function(entry){
this.sum +=entry;
++this.count;
},this);
}
let obj = new Counter();
obj.add([1,3,5,6]);
console.log(obj.count);//4
console.log(obj.sum);//15
示例:對(duì)象復(fù)制函數(shù)
//創(chuàng)建一個(gè)給定對(duì)象的副本
function copy(obj){
let copy = Object.create(Object.getPrototypeOf(obj));
let propNames = Object.getOwnPropertyNames(obj);
propNames.forEach(function(name){
let desc = Object.getOwnPropertyDescriptor(obj,name);
Object.defineProperty(copy,name,desc);
});
return copy;
}
let obj1 = { a:1,b:2};
let obj2 = copy(obj1);
console.log(obj1);//{a: 1, b: 2}
console.log(obj2);//{a: 1, b: 2}
示例:如果數(shù)組在迭代時(shí)被修改了,則其他元素會(huì)被跳過(guò)
let words = ['one','two','three','four'];
words.forEach(function(word){
console.log(word);
if(word === 'two'){
words.shift();
}
});
// one 、 tow 、 three
// 上面的代碼輸出one/two/four。當(dāng)?shù)竭_(dá)包含two的項(xiàng)時(shí),數(shù)組的第一個(gè)項(xiàng)被移除了,這導(dǎo)致所有剩下的項(xiàng)上移一個(gè)位置。因?yàn)樵豧our現(xiàn)在在數(shù)組更前的為孩子,three會(huì)被跳過(guò)。
map(),創(chuàng)建一個(gè)新數(shù)組,其結(jié)果是該數(shù)組中的每個(gè)元素都調(diào)用一個(gè)提供的函數(shù)后返回的結(jié)果。
返回一個(gè)新數(shù)組,每個(gè)元素都是回調(diào)函數(shù)的結(jié)果。
示例:
let numbers = [1,4,9];
let roots = numbers.map(Math.sqrt);//Math.sqrt只接受一個(gè)參數(shù),會(huì)自動(dòng)忽略map傳遞的后兩個(gè)參數(shù)
console.log(numbers);//[1, 4, 9]
console.log(roots);//[1, 2, 3]
// String上使用map放會(huì)獲取每一個(gè)字符
let res = Array.prototype.map.call('Hello World',function(x){
console.log(x);
return x.charCodeAt(0);//返回字符對(duì)應(yīng)的ASCII碼
});
console.log(res);//[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
// 注意:map的回調(diào)函數(shù)會(huì)接受三個(gè)參數(shù),在調(diào)用中需注意接受多個(gè)參數(shù)的函數(shù),如parseInt
// map中經(jīng)常使用箭頭函數(shù)
[].map((value,index,arr)=>{});//適用多種形式,此時(shí)thisArg參數(shù)無(wú)效,箭頭函數(shù)沒(méi)有this
filter(),創(chuàng)建一個(gè)新數(shù)組,其包含通過(guò)所提供函數(shù)實(shí)現(xiàn)的測(cè)試的所有元素。
filter為數(shù)組中的每個(gè)元素調(diào)用一次callback函數(shù),并利用所有使得callback返回true或等價(jià)于true的值的元素創(chuàng)建一個(gè)新數(shù)組。
返回一個(gè)新的通過(guò)測(cè)試的元素的集合的數(shù)組,如果沒(méi)有通過(guò)測(cè)試則返回空數(shù)組
示例:
// 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的搜索
let fruits = ['apple','banana','grapes','mango','orange'];
function filterItems(query){
return fruits.filter(function(el){
return el.toLowerCase().indexOf(query.toLowerCase())>-1;
})
}
console.log(filterItems('ap'));// ["apple", "grapes"]
console.log(filterItems('an'));// ["banana", "mango", "orange"]
console.log(fruits);// ["apple", "banana", "grapes", "mango", "orange"]
every(),測(cè)試數(shù)組的所有元素是否都通過(guò)了指定函數(shù)的測(cè)試。
every方法為數(shù)組中的每個(gè)元素執(zhí)行一次callback函數(shù),直到它找到一個(gè)使callback返回false(表示可轉(zhuǎn)換為布爾值false的值)的元素。如果發(fā)現(xiàn)了一個(gè)這樣的元素,every方法將會(huì)立即返回false。否則,callback為每一個(gè)元素返回true,every就會(huì)返回true。
every和數(shù)學(xué)中的“所有”類似,當(dāng)所有的元素都符合條件才返回true。另外,空數(shù)組也是返回true。(空數(shù)組中所有元素都符合給定的條件,注:因?yàn)榭諗?shù)組沒(méi)有元素)。
示例:
function isBigEnough(element,index,array){
console.log(element);// 12 、 130 、5
return (element >= 10);
}
let passed = [12,130,5,8,44].every(isBigEnough);
console.log(passed);// false
some(),測(cè)試是否至少有一個(gè)元素通過(guò)提供的函數(shù)實(shí)現(xiàn)的測(cè)試。
some()為數(shù)組中的每一個(gè)元素執(zhí)行一次callback函數(shù),直到找到一個(gè)使得callback返回一個(gè)真值。如果找到了這樣一個(gè)值,some()將會(huì)立即返回true。否則some()返回false。
示例:
function isBigEnough(element,index,array){
console.log(element);// 5 、 8 、12
return (element >= 10);
}
let passed = [5,8,12,3,130,44].some(isBigEnough);
console.log(passed);// true
find(),對(duì)數(shù)組中的每一項(xiàng)元素執(zhí)行一次callback函數(shù),直至有一個(gè)callback返回true。當(dāng)找到了這樣一個(gè)元素后,該方法會(huì)立即返回這個(gè)元素的值,否則返回undefined。
示例:查找數(shù)組中的質(zhì)數(shù)
function isPrime(element,index,array){
console.log(index);
let start = 2;
while(start <= Math.sqrt(element)){
if(element % start++ < 1){
return false
}
}
return element > 1;
}
console.log('res::'+[4,6,8,12].find(isPrime));
console.log('-----------')
console.log('res::'+[4,5,8,12].find(isPrime));
結(jié)果:可以看到當(dāng)找到一個(gè)質(zhì)數(shù)(5)后,便結(jié)束執(zhí)行。

示例:當(dāng)在回調(diào)中刪除數(shù)組中的一個(gè)值時(shí),當(dāng)訪問(wèn)到這個(gè)位置時(shí),其傳入的值為 undefined
let a=[0,1,,,,5,6];
a.find(function(value,index){
console.log('index::'+index+'& value::'+value);
});
console.log('----刪除后面的某個(gè)元素-----')
a.find(function(value,index){
if(index == 0){
console.log('del a[5]=='+a[5]);
delete a[5];
}
console.log('index=='+index+'& value == ' + value);
});
console.log('----刪除前面的某個(gè)元素----')
let arr=[0,1,2,3,4,5]
arr.find(function(value,index){
console.log('index=='+index+'& value == ' + value)
if(index == 2){
arr.shift();
}
});
結(jié)果:可以看到,無(wú)論未初始化的還是之后被刪除的都遍歷,值都為undefined。而在執(zhí)行過(guò)程中刪除元素,find還是會(huì)按照原來(lái)的索引去找當(dāng)前的索引對(duì)應(yīng)的值(索引3對(duì)應(yīng)成了4),即使數(shù)組長(zhǎng)度已經(jīng)不夠,也會(huì)訪問(wèn)到初始化時(shí)的最后一個(gè)索引(索引5對(duì)應(yīng)成了undefined)。

findIndex(),對(duì)數(shù)組中的每個(gè)數(shù)組索引0~length-1執(zhí)行一次callback函數(shù),知道找到一個(gè)callback函數(shù)返回真值。如果找到這樣的元素findIndex會(huì)立即返回該元素的索引。如果回調(diào)不返回真值,或者數(shù)組的length為0,則findIndex返回-1。
執(zhí)行規(guī)則基本與find相同,只是find返回的是值,而findIndex返回的是索引。
2. reduce/reduceRight方法與上面七個(gè)方法的語(yǔ)法類似,但有所不同,語(yǔ)法如下:
//fn代替reduce/reduceRight
arr.fn(callback[,initialValue]);
//參數(shù)
callback //執(zhí)行數(shù)組中每個(gè)值的函數(shù),包含四個(gè)參數(shù):
accumulator // 累計(jì)器,累計(jì)回調(diào)的返回值;它是上一次調(diào)用回調(diào)時(shí)返回的累積值,或initialValue(第一次)
currentValue // 數(shù)組中正在處理的元素
currentIndex // 可選,數(shù)組中正在處理的當(dāng)前元素的索引。如果提供了initialValue,則起始索引號(hào)為0,否則為1。
array //可選,調(diào)用reduce()的數(shù)組
initialValue //可選,作為第一次調(diào)用callback函數(shù)時(shí)的第一個(gè)參數(shù)的值。如果沒(méi)有提供初始值,則將使用數(shù)組中的第一個(gè)元素。在沒(méi)有初始值的空數(shù)組上調(diào)用reduce將報(bào)錯(cuò)。
// 返回值:函數(shù)累計(jì)處理的結(jié)果
幾點(diǎn)注意事項(xiàng):
① 回調(diào)函數(shù)第一次執(zhí)行時(shí),accumulator和currentValue的取值有兩種情況:如果調(diào)用時(shí)提供了initialValue,accumulator取值為initialValue,currentValue取數(shù)組中的第一個(gè)值;如果沒(méi)有提供initialValue,那么accumulator取數(shù)組中的第一個(gè)值,currentValue取數(shù)組中的第二個(gè)值。
② 如果數(shù)組為空且沒(méi)有提供initialValue,會(huì)拋出TypeError。如果數(shù)組僅有一個(gè)元素(無(wú)論位置如何)并且沒(méi)有提供initialValue,或者有提供initialValue但是數(shù)組為空,那么此唯一值將被返回并且callback不會(huì)被執(zhí)行。
③ 提供初始值通常更安全。
④ 數(shù)組中被刪除或從未被賦值的元素不會(huì)被執(zhí)行。
reduce(),對(duì)數(shù)組中的每個(gè)元素升序執(zhí)行提供的reducer函數(shù)(callback),將結(jié)果匯總為單個(gè)返回值。
示例:執(zhí)行過(guò)程中刪除第一個(gè)元素
let arr = [0,1,2,3,4];
let sum = arr.reduce(function(accumulator,currentValue,currentIndex){
console.log('currentIndex::' + currentIndex + '¤tValue::'+ currentValue);
if(currentIndex == 2){
arr.shift();
}
return accumulator + currentValue;
},0);
console.log('sum::' + sum);
結(jié)果:可以看到當(dāng)刪除第一個(gè),值3被跳過(guò),執(zhí)行索引3時(shí)對(duì)應(yīng)的值為4

示例:未初始化和執(zhí)行中被刪除的值
let arr = [0,1,,3,4,5];
let sum = arr.reduce(function(accumulator,currentValue,currentIndex){
console.log('currentIndex::' + currentIndex + '¤tValue::'+ currentValue);
if(currentIndex == 1){
delete arr[4];
}
return accumulator + currentValue;
},0);
console.log('sum::' + sum);
結(jié)果:可以看到索引2和索引4都被跳過(guò)

結(jié)合上面兩個(gè)示例,可以看到在遍歷執(zhí)行上reduce與forEach/map/filter/some/every規(guī)則相同。
示例:將二維數(shù)組轉(zhuǎn)化為一維
let flattened = [[0,1],[2,3],[4,5]].reduce(function(a,b){
return a.concat(b);
},[])
console.log(flattened);//[0, 1, 2, 3, 4, 5]
示例:計(jì)算數(shù)組中每個(gè)元素出現(xiàn)的次數(shù)
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;
},{});
console.log(countedNames);//{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}
示例:數(shù)組去重
let arr=[1,2,1,2,1,2,1,1,1,2,2,2,1];
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]
示例:按順序執(zhí)行Promise
function runPromiseInSequence(arr,input){
return arr.reduce(
(promiseChain,currentFunction)=>promiseChain.then(currentFunction),
Promise.resolve(input)
);
}
function p1(a) {
return new Promise((resolve, reject) => {
resolve(a * 5);
});
}
function p2(a) {
return new Promise((resolve, reject) => {
resolve(a * 2);
});
}
//這里f3也能正確觸發(fā)后面的p4,因?yàn)閒3可以被.then()封裝,所以只要reduce的第二個(gè)參數(shù)inititalValue是一個(gè)promise對(duì)象,則后面的函數(shù)都可以按順序執(zhí)行
function f3(a) {
return a * 3;
}
function p4(a) {
return new Promise((resolve, reject) => {
resolve(a * 4);
});
}
const promiseArr = [p1, p2, f3, p4];
runPromiseInSequence(promiseArr, 10).then(console.log); // 1200
reduceRight(),接受一個(gè)函數(shù)作為累加器(accumulator)和數(shù)組的每個(gè)值(從右到左)將其減少為單個(gè)值。
reduceRight運(yùn)行規(guī)則與reduce基本相同,只是遍歷的方向不同。
示例:將二維數(shù)組轉(zhuǎn)為一維數(shù)組
let flattened = [[0, 1], [2, 3], [4, 5]].reduceRight(function(a, b) {
return a.concat(b);
}, []);
console.log(flattened); //[4, 5, 2, 3, 0, 1]
示例:reduce與reduceRight之間的區(qū)別
let a=['1','2','3','4','5'];
let left = a.reduce(function(prev,cur){ return prev + cur;});
let right = a.reduceRight(function(prev,cur){return prev+cur;});
console.log(left);//'12345'
console.log(right);//'54321'
第三類,獲取鍵值:entries/keys/values
entries(),返回一個(gè)新的Array Iterator對(duì)象,該對(duì)象包含數(shù)組中每個(gè)索引的鍵/值對(duì)。
語(yǔ)法: arr.entries()
返回值:一個(gè)新的Array迭代器對(duì)象。
示例:
let arr = ['a','b','c'];
let iterator = arr.entries();
console.log(iterator);
console.log('----------------')
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log('----------------')
for( let e of iterator){
console.log(e);//什么也沒(méi)打印
}
console.log('----------------')
let iterator1=arr.entries();
for(let e of iterator1){
console.log(e);//有打印輸出
}
console.log(iterator1.next());
結(jié)果:此處注意迭代器的next()方法

keys(),返回一個(gè)包含數(shù)組中每個(gè)索引鍵的Array Iterator對(duì)象。
語(yǔ)法:arr.keys()。
返回值:一個(gè)新的Array迭代器對(duì)象。
示例:迭代器對(duì)象會(huì)包含那些沒(méi)有對(duì)應(yīng)元素的索引
let arr = ['a',,'c'];
let sparseKeys = Object.keys(arr);
let denseKeys = [ ...arr.keys()];
console.log(sparseKeys);//["0", "2"]
console.log(denseKeys);//[0, 1, 2]
values(),返回一個(gè)新的Array Iterator對(duì)象,該對(duì)象包含數(shù)組每個(gè)索引的值。
語(yǔ)法:arr.values()?;九ckeys()相同,參照使用。
第四類,查找元素:indexOf/lastIndexOf/includes
這三個(gè)方法的語(yǔ)法類似:
// fn代替indexOf/lastIndexOf/includes
arr.fn(searchElement,fromIndex);
// 參數(shù)
searchElement // 需要查找的元素值。
fromIndex // 可選,開(kāi)始查找的位置。由于indexOf和includes是從左到右查找,而lastIndexOf是從右到左查找,所以這個(gè)參數(shù)的規(guī)則有所不同
// indexOf/includes: 默認(rèn)值為0,從左到右正向查找。
// 如果該索引值大于或等于數(shù)組長(zhǎng)度,意味著不會(huì)在數(shù)組里查找,返回-1,includes返回false;
// 如果參數(shù)中提供的索引值是一個(gè)負(fù)值,則將其作為數(shù)組末尾的一個(gè)抵消,即表示從length-|fromIndex|開(kāi)始查找;
// 如果參數(shù)中提供的索引值是一個(gè)負(fù)值,并不改變其查找順序,查找順序仍然是從前向后查詢數(shù)組。
// 如果抵消后的索引值仍小于0,則整個(gè)數(shù)組都將會(huì)被查詢。
// lastIndexOf: 默認(rèn)值為數(shù)組的長(zhǎng)度減1,從右到做逆向查找。
// 如果該值為負(fù)時(shí),其絕對(duì)值大于數(shù)組長(zhǎng)度,則方法返回-1,即數(shù)組不會(huì)被查找。
// 如果為負(fù)值,將其視為從數(shù)組末尾向前的偏移(length-|fromIndex|)。
// 即使該值為負(fù),數(shù)組仍然會(huì)被從后向前查找。
// 如果該值大于或等于數(shù)組的長(zhǎng)度,則整個(gè)數(shù)組會(huì)被查找。
它們?nèi)齻€(gè)判斷均使用嚴(yán)格相等(===)進(jìn)行比較,區(qū)分大小寫。
indexOf(),返回在數(shù)組中可以找到一個(gè)給定元素的第一個(gè)索引,如果不存在,則返回-1。
返回首個(gè)被找到的元素在數(shù)組中的索引位置;若沒(méi)有找到則返回-1。
示例:找出指定元素出現(xiàn)的所有位置
let includes=[];
let arr=['a','b','a','c','a','d'];
let element = 'a';
let idx = arr.indexOf(element);
while(idx!=-1){
includes.push(idx);
idx = arr.indexOf(element,idx+1);
}
console.log(includes);//[0, 2, 4]
lastIndexOf(),返回指定元素(也即有效的JavaScript值或變量)在數(shù)組中的最后一個(gè)的索引,如果不存在則返回-1。
返回?cái)?shù)組中最后一個(gè)元素的索引,如果未找到返回-1。
用法規(guī)則參照indexOf。
includes(),用來(lái)判斷一個(gè)數(shù)組是否包含一個(gè)指定的值,根據(jù)情況,如果包含則返回true,否則返回false。
示例:includes()方法有意設(shè)計(jì)為通用方法。它不要求this值是數(shù)組對(duì)象,所以它可以被用于其它類型的對(duì)象(比如類數(shù)組對(duì)象)。
(function() {
console.log([].includes.call(arguments, 'a')); // true
console.log([].includes.call(arguments, 'd')); // false
})('a','b','c');
第五類,數(shù)組轉(zhuǎn)變?yōu)镾tring:join/toString/toLocaleString
join(),將一個(gè)數(shù)組(或一個(gè)類數(shù)組對(duì)象)的所有元素連接成一個(gè)字符串并返回這個(gè)字符串。
join()方法不會(huì)改變數(shù)組本身。
如果元素是undefined或者null,則會(huì)轉(zhuǎn)化成空字符串。
語(yǔ)法:
let str = arr.join(separator);
// 參數(shù)
separator // 指定一個(gè)字符串來(lái)分隔數(shù)組的每個(gè)元素。
// 如果需要(separator),將分隔符轉(zhuǎn)換為字符串。
// 如果省略(),數(shù)組元素用逗號(hào)分隔。默認(rèn)為“,”。
// 如果separator是空字符串(''),則所有元素之間都沒(méi)有任何字符。
// 返回值:一個(gè)所有數(shù)組元素連接的字符串。如果arr.length為0,則返回空字符串。
示例:
let arr = [1,2,'',undefined,null,true,false];
let str = arr.join();
console.log(str);//1,2,,,,true,false
console.log(arr);//[1, 2, "", undefined, null, true, false]
arr.length = 0;
console.log(arr);//[];
示例:應(yīng)用于類數(shù)組對(duì)象
function fn(a,b,c){
let s = Array.prototype.join.call(arguments);
console.log('fn::',s);
}
fn(1,'a','undefined');
function ff(a,b,c){
arguments.length = 0;
console.log('ff>arguments::',arguments);
let s = Array.prototype.join.call(arguments);
console.log('ff::',s);
}
ff(1,'a','undefined');
結(jié)果:可以看到,數(shù)組設(shè)置length為0后數(shù)組相當(dāng)于被刪除,而類數(shù)組對(duì)象的length設(shè)置為0后屬性還在,但是輸出的同樣是一個(gè)空字符串,所以length屬性對(duì)join影響很大。(可以測(cè)試,將arugments的length設(shè)置為1,則只有索引為0的元素被轉(zhuǎn)化返回了)

toString(),返回一個(gè)字符串,表示指定的數(shù)組及其元素。
語(yǔ)法:arr.toString();
返回值:一個(gè)表示指定的數(shù)組及其元素的字符串。
Array對(duì)象覆蓋了Object的toString方法。對(duì)于數(shù)組對(duì)象,toString方法連接數(shù)組并返回一個(gè)字符串,其中包含用逗號(hào)分隔的每個(gè)數(shù)組元素。
示例:當(dāng)一個(gè)數(shù)組被作為文本值或者進(jìn)行字符串連接操作時(shí),將會(huì)自動(dòng)調(diào)用其toString方法
console.log('a'+[1,2,3,4]); //a1,2,3,4
console.log('a'+[1,2,3,4].toString()); //a1,2,3,4
toLocaleString(),返回一個(gè)字符串表示數(shù)組中的元素。數(shù)組中的元素將使用各自的toLocaleString方法轉(zhuǎn)成字符串,這些字符串將使用一個(gè)特定的語(yǔ)言環(huán)境的字符串(例如一個(gè)逗號(hào))隔開(kāi)。
語(yǔ)法:
arr.toLocaleString([locales[,opitons]]);
// 參數(shù)
locales //可選,帶有BCP 47語(yǔ)言標(biāo)記的字符串或字符串?dāng)?shù)組,關(guān)于locales參數(shù)的形式與解釋:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Intl
optionds //可選,一個(gè)可配置屬性的對(duì)象,對(duì)于數(shù)字Number.prototype.toLocaleString(),對(duì)于日期Date.prototype.toLocaleString()。
// 返回值:表示數(shù)組元素的字符串
注:這塊參數(shù)方面還很懵逼,有時(shí)間回頭要好好看看!切記回看
第六類,數(shù)組排序:sort/reverse
sort(),方法用原地算法對(duì)數(shù)組的元素進(jìn)行排序,并返回?cái)?shù)組。
由于它取決于具體實(shí)現(xiàn),因此無(wú)法保證排序的時(shí)間和空間復(fù)雜性。
語(yǔ)法:
arr.sort([compareFunction]);
// 參數(shù)
compareFunction //可選,用來(lái)指定按某種順序進(jìn)行排列的函數(shù)。如果省略,元素按照轉(zhuǎn)換為的字符串的各個(gè)字符的Unicode位點(diǎn)進(jìn)行排序。
firstEL // 第一個(gè)用于比較的元素
secondEL // 第二個(gè)用于比較的元素
// 返回值:排序后的數(shù)組。注意:數(shù)組已原地排序,并且不進(jìn)行復(fù)制。
如果沒(méi)有指明compareFunction,那么元素會(huì)按照轉(zhuǎn)換為的字符串的諸個(gè)字符的Unicode位點(diǎn)進(jìn)行排序。
如果指明了compareFunction,那么數(shù)組會(huì)按照調(diào)用該函數(shù)的返回值排序。
- 如果 compareFunction(a, b) 小于 0 ,那么 a 會(huì)被排列到 b 之前
- 如果 compareFunction(a, b) 等于 0 , a 和 b 的相對(duì)位置不變。備注: ECMAScript 標(biāo)準(zhǔn)并不保證這一行為,而且也不是所有瀏覽器都會(huì)遵守(例如 Mozilla 在 2003 年之前的版本);
- 如果 compareFunction(a, b) 大于 0 , b 會(huì)被排列到 a 之前。
- compareFunction(a, b) 必須總是對(duì)相同的輸入返回相同的比較結(jié)果,否則排序的結(jié)果將是不確定的。
示例:可以看到數(shù)組本身會(huì)被修改
let arr1=['cherry','Banana'];
console.log(arr1.sort());//["Banana", "cherry"]
console.log(arr1);//["Banana", "cherry"]
//比較的數(shù)字會(huì)先被轉(zhuǎn)換為字符串,所以在Unicode順序上 "80" 要比 "9" 要靠前
let arr2 = [9,80,23,53,7,3];
console.log(arr2.sort());//[23, 3, 53, 7, 80, 9]
console.log(arr2);//[23, 3, 53, 7, 80, 9]
reverse(),將數(shù)組中的元素位置顛倒。第一個(gè)數(shù)組元素成為最后一個(gè)數(shù)組元素,最后一個(gè)數(shù)組元素成為第一個(gè)。
語(yǔ)法:arr.reverse();。reverse 方法顛倒數(shù)組中元素的位置,并返回該數(shù)組的引用。
示例:
let myarr = ['one','two','three'];
let copyarr = myarr.reverse();
console.log(myarr);//["three", "two", "one"]
console.log(copyarr);//["three", "two", "one"]
console.log(copyarr === myarr);//true