JS數組中的方法以及對應的Polyfill

/**
 * copyWithin(): 方法淺複製數組的一部分到同一數組中的另一個位置,並返回它,不會改變原數組的長度。
 * entries(): 方法返回一個新的Array Iterator對象,該對象包含數組中每個索引的鍵/值對。
 * Array.prototype.fill() : 用一個固定值填充一個數組中從起始索引到終止索引內的全部元素,arr.fill(value[, start[, end]])
 * Array.prototype.find() : 方法返回數組中滿足提供的測試函數的第一個元素的值。否則返回 undefined。
 * Array.prototype.findIndex() : 方法返回數組中滿足提供的測試函數的第一個元素的索引。否則返回-1。
 * Array.prototype.flat() : 方法會按照一個可指定的深度遞歸遍歷數組,並將所有元素與遍歷到的子數組中的元素合併爲一個新數組返回。
 * Array.prototype.flatMap() : 方法首先使用映射函數映射每個元素,然後將結果壓縮成一個新數組。它與 map 連着深度值爲1的 flat 幾乎相同,但 flatMap 通常在合併成一種方法的效率稍微高一些。
 * Array.prototype.keys() : 返回一個包含數組中每個索引鍵的Array Iterator對象
 * Array.prototype.values() : 返回一個包含數組中每個索引鍵的Array Iterator對象
 * lastIndexOf() 方法返回指定元素(也即有效的 JavaScript 值或變量)在數組中的最後一個的索引,如果不存在則返回 -1。從數組的後面向前查找,從 fromIndex 處開始
 */

/** 1、Array.isArray() */
    Array.isArray([1,2]) // true
    Array.isArray(Array.prototype);// 鮮爲人知的事實:其實 Array.prototype 也是一個數組。

    /** Polyfill */
    Array.isArray = function(arg){
        return Object.prototype.toString.call(arg) === '[Obejct Array]';
    }

/** 2、Array.form() : 從一個類似數組或可迭代對象創建一個新的,淺拷貝的數組實例 */
    Array.from('abcd');// ['a', 'b', 'c', 'd']                         ---- 新數組
    Array.from(new Set(['a', 'b', 'c', 'd'])); // ['a', 'b', 'c', 'd'] ---- 從Set中 新數組
    Array.from(new Map([[1,2], [3,4]])); // [[1,2], [3,4]]             ---- 從Map中 新數組
    function fun() {
        return Array.from(arguments); // fun(1,2,3);// [1,2,3]         ---- 從數組對象中
    }
    Array.from(new Set([1,2,2,3,1,3])); // 【1,2,3】                   ----- 數組去重

    /** Polyfill */ // 情況有點多 MDN

/** 3、 Array.of() : 變量變數組*/
    Array.of(1, 2, 3, 'str', '5'); // [1,2,3,'str','5']
    /** Polyfill */
    Array.of = function() {
        return Array.prototype.slice.call(arguments);
    };

/** 4、 Array.prototype.concat() : 合併(連接)兩個或多個數組,返回新數組,不修改現有數組   !!!:淺拷貝  */
    let arr1 = ['a', 'b', 'c'], arr2 = ['d', 'e', 'f'];
    console.log(arr1.concat(arr2)); // ["a", "b", "c", "d", "e", "f"]

    /** Polyfill */

/** 5、 Array.prototype.every() :  測試一個數組內的所有元素是否能通過指定函數的邏輯,返回Boolean*/
    let arr = [1, 2, 3, 4, 5];
    console.log(arr.every((item, index, array) => { return item > 0; })); // true

    /** Polyfill */
    Array.prototype.every = function (callback) {
        let res = true;
        for (let i = 0; i < this.length; i++) {
            if(!callback(this[i], i, this)) res = false;
        }
        return res;
    }

/** 6、 Array.prototype.some() :  測試數組中是不是至少有1個元素通過了被提供的函數測試,返回Boolean*/
    let arr = [1, 2, 3, 4, 5];
    console.log(arr.some((item, index, array) => { return item > 4; })); // true

    /** Polyfill */
    Array.prototype.some = function (callback) {
        let res = false;
        for (let i = 0; i < this.length; i++) {
            if(callback(this[i], i, this)) res = true;
        }
        return res;
    }

/** 7、 Array.prototype.filter() : 返回一個新數組, 其包含通過所提供函數實現的測試的所有元素   !!!:淺拷貝  */
    let arr = [1, 2, 3, 5];
    console.log(arr.filter((item, index, array)=>{ return item > 0; }));

    /** Polyfill */
    Array.prototype.filter = function (callback) {
        let res = [], index = 0;
        for (let i = 0; i < this.length; i++) {
            if(callback(this[i], i, this)){
                res[index] = this[i];
                index++;
            }
        }
        return res;
    }

/** 8、 Array.prototype.forEach() : 方法對數組的每個元素執行一次提供的函數。 */
    let arr = [1, 2, 3, 5];
    arr.forEach((item, index, array)=>{ console.log(item) })
    // !!!: 沒有辦法中止或者跳出 forEach() 循環,除了拋出一個異常。
    // !!!: callback 如果數組在迭代時被修改了,則其他元素會被跳過。不能在循環內使用 刪除或者添加操作

    /** Polyfill */
    Array.prototype.forEach = function (callback) {
        for (let i = 0; i < this.length; i++) {
            callback(this[i], i, this);
        }
    }

/** 9、 Array.prototype.includes() : 方法用來判斷一個數組是否包含一個指定的值 arr.includes(value, index) */
    [1, 2, 3].includes(2);     // true
    [1, 2, 3].includes(3, 3);  // false
    [1, 2, 3].includes(3, -1); // true
    [1, 2, NaN].includes(NaN); // true

/** 10、 Array.prototype.indexOf() : 方法返回在數組中可以找到一個給定元素的第一個索引,如果不存在,則返回-1 */
    // 
    /** Polyfill */
    // 循環返回下標,如果沒有,返回-1

/** 11、 Array.prototype.join() : 將一個數組(或一個類數組對象)的所有元素連接成一個字符串並返回這個字符串。如果數組只有一個項目,那麼將返回該項目而不使用分隔符 */
    let arr = ['Fire', 'Air', 'Water'];
    console.log(elements.join()); // "Fire,Air,Water"    // 如果缺省該值,數組元素用逗號(,)分隔
    console.log(elements.join('')); // "FireAirWater"
    console.log(elements.join('-')); // "Fire-Air-Water"

/** 12、 Array.prototype.map() : 返回一個新數組,該數組中的每個元素都調用一個提供的函數後返回的結果  !!!: 淺拷貝 */
    // map 不修改調用它的原數組本身(當然可以在 callback 執行時改變原數組)
    var numbers = [1, 4, 9];
    var roots = numbers.map(Math.sqrt);
    // roots的值爲[1, 2, 3], numbers的值仍爲[1, 4, 9]
    // arr.map(callback(item, index, arr))

    /** Polyfill */
    Array.prototype.map = function (callback) {
        let res = [];
        for (let i = 0; i < this.length; i++) {
            res.push(callback(this[i], i, this))
        }
        return res;
    }

/** 13、 Array.prototype.pop() : 從數組中刪除最後一個元素,並返回該元素的值。此方法更改數組的長度 */
    let myFish = ["angel", "clown", "mandarin", "surgeon"];
    let popped = myFish.pop();
    console.log(myFish); // ["angel", "clown", "mandarin"]
    console.log(popped); // surgeon
/** 14、 Array.prototype.shift() : 從數組中刪除第一個元素,並返回該元素的值。此方法更改數組的長度 */


/** 15、 Array.prototype.push() : 將一個或多個元素添加到數組的末尾,並返回該數組的新長度 */
    // 合併兩個數組,  使用 apply() 添加第二個數組的所有元素
    var vegetables = ['parsnip', 'potato'];
    var moreVegs = ['celery', 'beetroot'];
    // 將第二個數組融合進第一個數組
    // 相當於 vegetables.push('celery', 'beetroot');
    Array.prototype.push.apply(vegetables, moreVegs);
    console.log(vegetables); 
    // ['parsnip', 'potato', 'celery', 'beetroot']

    /** Polyfill */
    Array.prototype.push = function () {
        for (let i = 0; i < arguments.length; i++) {
            this[this.length] = arguments[i] 
        }
        return this.length;
    }

/** 16、 Array.prototype.unshift() : 將一個或多個元素添加到數組的開頭,並返回該數組的新長度(該方法修改原有數組 */

    /** Polyfill */
    Array.prototype.unshift = function () {
        ///定義一個數組保存當前數組的值和newUnShift方法傳遞進來的參數
        var newArr = [];
        //循環newUnShift方法傳遞進來的參數並保存到newArr中
        for(var i=0;i<arguments.length;i++){
            newArr[i] = arguments[i];
        }
        var len = newArr.length;
        //循環當前要添加數組 也保存在newArr中
        for(var j=0;j<this.length;j++){
            newArr[ parseInt(len+j) ] = this[j];
        }
        //重新給當前數組插入合併後的數組值
        for(var k=0;k<newArr.length;k++){
            this[k] = newArr[k];
        }
        return this.length;
    }

/** 17、 Array.prototype.reduce() :  對數組中的每個元素執行一個由您提供的reducer函數(升序執行),將其結果彙總爲單個返回值 */
    // reducer 函數接收4個參數 ,一個功能強大的函數
    // arr.reduce(callback(累計器, 當前值, 當前索引, 原數組))
    // 詳細參考MDN

/** 18、 Array.prototype.reduce() :  將數組中元素的位置顛倒,並返回該數組。該方法會改變原數組 */
    let arr = [1, 2, 3];
    arr.reverse(); console.log(arr); // [3, 2, 1]

    /** Polyfill */
    Array.prototype.reverse = function () {
        let res = []; 
        for (let i = 0; i < this.length; i++) {
            res[i] = this[this.length - i - 1]
        }
        return res;
    }

/** 19、 Array.prototype.slice() :  返回一個新的數組對象,這一對象是一個由 begin 和 end 決定的原數組的淺拷貝(包括 begin,不包括end)。原始數組不會被改變 */
    let arr = ['ant', 'bison', 'camel', 'duck', 'elephant'];
    let arr1 = arr.slice(1, 3); // ['bison', 'camel'] // 包括 begin,不包括end
    let arr2 = arr.slice(-2); //["duck", "elephant"] 倒數第二個元素到最後一個元素

    /** Polyfill */
    Array.prototype.slice = function(a, b){
        // 如果a是負數,另添加判斷
        a=a||0;
        b=b||this.length;
        var ary=[];
        for(var i=a; i<b; i++){
            ary.push(this[i]);
        }
        return ary;
    }

/** 20、 Array.prototype.splice() :  通過刪除或替換現有元素或者原地添加新的元素來修改數組,並以數組形式返回被修改的內容。此方法會改變原數組 */
    var myFish = ["angel", "clown", "mandarin", "sturgeon"];
    var removed = myFish.splice(2, 0, "drum"); 
    // removed = []; 插入 沒有值
    // ["angel", "clown", "drum", "mandarin", "sturgeon"]  ----  插入元素  
    var removed = myFish.splice(3, 1); 
    // removed = ["sturgeon"]
    // 運算後的 myFish: ["angel", "clown", "mandarin"]      從第 3 位開始刪除 1 個元素
    var removed = myFish.splice(2, 1, "trumpet");
    // 運算後的 myFish: ["angel", "clown", "trumpet", "sturgeon"]
    // 被刪除的元素: ["drum"]

    /** Polyfill */
    Array.prototype.splice = function(){
        var index,howmany;
        if(arguments.length == 0){
            this.length = 0;
            return this;
        }else if(arguments.length == 1){        //調整index和howmany的值
            index = arguments[0];
            if(index >= this.length){
                index = this.length;
            }else if(index < -this.length){
                index = 0;
            }else if(index < 0 && index >= -(this.length)){
                index += this.length;
            }
            howmany = this.length - index;
        }else if(arguments.length >= 2){        //調整index和howmany的值
            index = arguments[0];
            if(index >= this.length){
                index = this.length;
            }else if(index < -this.length){
                index = 0;
            }else if(index < 0 && index >= -(this.length)){
                index += this.length;
            }
            howmany = arguments[1];
            if(index+howmany >= this.length){
                howmany = this.length - index;
            }
    
        }
        var t1 = index;
        var length = arguments.length - 2;
        var arr = [];
        for(var i = 0 ; i < howmany ; i++){             // 返回刪除的數組
            arr[i] = this[t1++];
        }
        var t2 = index;
        for(var i = t2 + howmany ; i < this.length ; i++){  //刪除操作後的數組
            this[t2++] = this[i];
        }
        this.length = this.length - howmany;
    
        if(arguments.length > 2){                            //插入數
            var lastLength = this.length; 
            var leap = lastLength - index;
            var arIndexRigtht = arguments.length - 1;
            this.length = this.length + arguments.length - 2;
            for(var j = this.length - 1 ; j >= index ; j--){        
                if(leap > 0){
                    this[j] = this[j - arguments.length + 2];
                    leap = leap -1 ;
                }else{
                    this[j] = arguments[arIndexRigtht--];
                }
            }
        }
        return arr;
    }

/** 21、 Array.prototype.sort() :  用原地算法對數組的元素進行排序,並返回數組。默認排序順序是在將元素轉換爲字符串,然後比較它們的UTF-16代碼單元值序列時構建的 */
    // arr.sort([compareFunction])  compareFunction(arg1, arg2): arg1\arg2 要比較的值
    // 1、按照值比較
    var numbers = [4, 2, 5, 1, 3]; 
    numbers.sort((a, b) => { return a - b; }); 
    console.log(numbers); // [1, 2, 3, 4, 5]
    // 按照屬性 比較
    var items = [ { name: 'Edward', value: 21 }, { name: 'Sharpe', value: 37 }, { name: 'And', value: 45 }];
    items.sort((a, b) => { return (a.value - b.value) });
    items.sort((a, b) => {
        var nameA = a.name.toUpperCase();
        var nameB = b.name.toUpperCase();
        if (nameA < nameB) return -1;
        if (nameA > nameB) return 1;
        return 0;// names must be equal
    });
    // 亂序
    arr.sort(function(a, b){ return Math.random() - 0.5; }); // 擴展
    /** Polyfill */

/** 22、 Array.prototype.toLocaleString() : 返回一個字符串表示數組中的元素。數組中的元素將使用各自的 toLocaleString 方法轉成字符串,這些字符串將使用一個特定語言環境的字符串 */
    parseInt('11123123231.3213').toLocaleString();  //  "11,123,123,231"      千位分隔符
    [1,'231',3,4].toLocaleString();   // "1, 231, 3, 4"

/** 23、 Array.prototype.toString() : 返回一個字符串,表示指定的數組及其元素。 */
    [1, 2, 'a', '1a'].toString();   // "1, 2, a, 1a"
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章