全面認(rèn)識(shí)JavaScript的Array對(duì)象

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

========== 屬性 ==========

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ù)組一樣
push
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ì)被遍歷
foreach1
示例:使用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í)行。
find
示例:當(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)。
find
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 + '&currentValue::'+ 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
reduce1
示例:未初始化和執(zhí)行中被刪除的值

    let arr = [0,1,,3,4,5];
    let sum = arr.reduce(function(accumulator,currentValue,currentIndex){
        console.log('currentIndex::' + currentIndex + '&currentValue::'+ currentValue);
        if(currentIndex == 1){
            delete arr[4];
        }
        return accumulator + currentValue;
    },0);
    console.log('sum::' + sum);

結(jié)果:可以看到索引2和索引4都被跳過(guò)
reduce2

結(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()方法
entries
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)化返回了)
join
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


參考:MDN javascript標(biāo)準(zhǔn)庫(kù) Array

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容