JS数组常用方法整理

828 阅读15分钟

原数组改变

pop

/*
* 作用:从数组中删除最后一个元素
* 语法:[原数组].pop()
*   @params
*       无
*   @return
*       删除的元素;如果数组为空,返回undefined
* */
{
    let arr = [1, 2, 3, 4];
    let delValue = arr.pop();
    console.log(delValue, arr); //=> 4 [ 1, 2, 3 ]
}

push

/*
* 作用:将一个或多个元素追加到数组末尾,并返回数组长度
* 语法:let lenght = [原数组].push([val],[val].......)
*   @params
*       val:追加到数组末尾的元素
*   @return
*       改变后的数组长度
* */
{
    let arr = [1, 2, 3, 4];
    let length = arr.push(5, 6);
    console.log(length, arr); //=> 6 [ 1, 2, 3, 4, 5, 6 ]
}

shift

/*
* 作用:从数组中删除第一个元素
* 语法:let delValue = [原数组].shift()
*   @params
*       无
*   @return
*       删除的元素;如果数组为空,返回undefined
* */
{
    let arr = [1, 2, 3, 4];
    let delValue = arr.shift();
    console.log(delValue, arr); //=> 1 [ 2, 3, 4 ]
}

unshift

/*
* 作用:将一个或多个元素添加到数组的开头,并返回数组长度
* 语法:let length = [原数组].unshift([val],[val])
*   @params
*       val:添加的元素
*   @return
*       修改后的数组长度
* 注意:调用一次添加多个元素,和调用多次(每次添加一个元素),将得到不同顺序的结果
* */
{
    let arr = [1, 2, 3, 4];
    let length = arr.unshift(0);
    console.log(length, arr); //=> 5 [ 0, 1, 2, 3, 4 ]
}

reverse

/*
* 作用:数组倒序
* 语法:let newArr = [原数组].reverse()
*   @params
*       无
*   @return
*       倒序后的数组
* */
{
    let arr = [1, 2, 3, 4];
    let newArr = arr.reverse();
    console.log(newArr, arr); //=> [ 4, 3, 2, 1 ] [ 4, 3, 2, 1 ]
}

splice

/*
* 作用:通过删除,或者替换现有元素,或者添加元素,以达到修改数组,并以数组形式返回被修改的内容
* 语法:let delArr = [原数组].splice([start],[delCount],[val],[val],...)
*   @params
*       start:起始索引。
*              若大于数组长度,从数组末尾开始追加内容;
*              若为负数,等同于数组长度+start;
*              若为负数,且绝对值大于数组长度,则为0;
*       delCount:移除的数组个数。
*              如果没写,或者个数大于start后面的元素总个数,则删除start后面的所有元素;
*              如果是0或负数,则不删除元素
*       val:添加进数组的元素,如果不写,则只做删除元素操作
*   @return
*       被删除的数组组成的一个数组。如果没有删除元素,返回空数组。
* */

// 只删除元素
{
    let arr = [1, 2, 3, 4];
    let delArr = arr.splice(1, 1);
    console.log(arr, delArr); //=> [ 1, 3, 4 ] [ 2 ]
}

// 只添加元素
{
    let arr = [1, 2, 3, 4];
    let delArr = arr.splice(0, 0, 0);
    console.log(arr, delArr); //=> [ 0, 1, 2, 3, 4 ] []
}

sort

/*
* 作用:数组排序
* 语法:let newArr = [原数组].sore(fun([a],[b]))
*   @params
*       cb:用来指定按某种顺序进行排列的函数
*           a:第一个用于比较的元素
*           b:第二个用于比较的元素
*   @return
*       排序后的数组
* 注意:默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列
* */
{
    let arr = [1, 2, 3, 4];
    let newArr = arr.sort(function (a, b) {
        // return a - b //=> 升序
        return b - a //=> 降序
    })
    console.log(arr, newArr); //=> [ 4, 3, 2, 1 ] [ 4, 3, 2, 1 ]
}

copyWith

/*
* 作用:浅拷贝数组的一部分内容,到数组中的另一个位置,并返回
* 语法:let [新数组] = [原数组].copyWith([target,start,end])
*   @params
*       target:索引,粘贴的起始位置。如果是负数,从末尾开始计算;如果大于数组长度,不拷贝;
*       start:索引,拷贝的起始位置。如果是负数,从末尾开始计算;如果没有,则默认为0;
*       end:索引,拷贝的结束位置,但不包括自身。如果是负数,从末尾开始计算;如果没有,则默认为数组长度;
*   @return
*       改变后的数组
* 注意:target,start,end必须为整数
* */
{
    let arr = [1, 2, 3, 4, 5];
    let newArr = arr.copyWithin(-1);
    console.log(arr, newArr);//=> [ 1, 2, 3, 4, 1 ] [ 1, 2, 3, 4, 1 ]
}
{
    let arr = [1, 2, 3, 4, 5];
    let newArr = arr.copyWithin(0, 3)
    console.log(arr, newArr);//=> [ 4, 5, 3, 4, 5 ] [ 4, 5, 3, 4, 5 ]
}
{
    let arr = [1, 2, 3, 4, 5];
    let newArr = arr.copyWithin(-2, -3, -1);
    console.log(arr, newArr);//=> [ 1, 2, 3, 3, 4 ] [ 1, 2, 3, 3, 4 ]
}

fill

/*
* 作用:用一个固定的值,替换掉数组中指定起始位置到结束位置的全部元素
* 语法:let [新数组] = [原数组].fill([value],[start],[end])
*   @params
*       value:用来替换的那个值;
*       start:索引,替换的起始位置;如果是负数,则为数组长度+start;如果不写,默认为0;
*       end:索引,替换的结束位置,不包括自身;如果是负数,则为数组长度+end;如果不写,默认为数组长度;
*   @return
*       修改后的数组
* 注意:如果替换的值是引用类型,则被替换的元素引用的是同一个引用地址。
* */

// 替换的元素是值类型
{
    let arr = [1, 2, 3, 4, 5];
    let newArr = arr.fill('a', 0, 2);
    console.log(arr, newArr); //=> [ 'a', 'a', 3, 4, 5 ] [ 'a', 'a', 3, 4, 5 ]
    newArr[0] = 'b';
    console.log(arr, newArr); //=> [ 'b', 'a', 3, 4, 5 ] [ 'b', 'a', 3, 4, 5 ]
}

// 替换的元素是引用类型
{
    let arr = [1, 2, 3, 4, 5];
    let newArr = arr.fill({}, 0, 2);
    console.log(arr, newArr); //=> [ {}, {}, 3, 4, 5 ] [ {}, {}, 3, 4, 5 ]
    newArr[0].str = 'string';
    console.log(arr, newArr); //=> [ { str: 'string' }, { str: 'string' }, 3, 4, 5 ] [ { str: 'string' }, { str: 'string' }, 3, 4, 5 ]
}

原数组不变

slice

/*
* 作用:浅拷贝了原数组中指定起始索引和结束索引的元素,返回一个新的数组对象
* 语法:let newArr = [原数组].slice(start,end)
*   @params
*       start:起始索引。
*              如果写负数,表示数组中倒数第几个元素开始;
*              如果不写,则从0开始;
*       end:结束索引。不包含本身;
*              如果写负数,则表示数组中倒数第几个元素结束;
*              如果不写或大于数组长度,则提取到数组末尾;
*   @return
*       含有被提取元素的新数组
* 注意:如果元素是引用数据类型,则会拷贝这个对象引用到新数组中,原数组对应元素和新数组对应元素是同一地址引用;
*      如果元素是值数据类型,直接拷贝值到新数组;
*      新旧数组任意一个添加新元素,另一个不受影响;
* */

// 元素是值数据类型
{
    let arr = [1, 2, 3, 4];
    let newArr = arr.slice(1, 2);
    console.log(arr, newArr); //=> [ 1, 2, 3, 4 ] [ 2 ]
}

// 元素是引用数据类型
{
    let arr = [{a: 1}, {a: 2}];
    let newArr = arr.slice(0, 1);
    console.log(arr, newArr); //=> [ { a: 1 }, { a: 2 } ] [ { a: 1 } ]
    newArr[0].a = 20;
    console.log(arr, newArr); //=> [ { a: 20 }, { a: 2 } ] [ { a: 20 } ]
}

concat

/*
* 作用:用于合并两个或多个数组。
* 语法:let [新数组] = [源数组].concat([val].....)
*   @params
*       val:[Object]/[String]/[Bollean]/[Number]
*   @return
*       新的Array实例(浅拷贝)
* 注意:当被连接的元素不是引用类型时,对新数组的任何操作,不会影响原始数组。反之亦然。
* */

// 值数据类型
{
    let arr = [1, 2, 3];
    let str = 'a';
    let num = 1;
    let boll = true;
    let newArr = arr.concat(str, num, boll);
    console.log(newArr); //=> [ 1, 2, 3, 'a', 1, true ]
    boll = false; // 改变元素
    console.log(newArr); //=> [ 1, 2, 3, 'a', 1, true ] => 新数组没有改变
    arr.push(4); // 改变源数组元素
    console.log(newArr); //=>  [ 1, 2, 3, 'a', 1, true ] => 新数组没有改变
}

// 引用数据类型
{
    let arr = [[1]];
    let arrCon = [[2]];
    let newArr = arr.concat(arrCon);
    console.log(newArr); //=> [ [ 1 ], [ 2 ] ]
    arrCon[0].push(3); // 被连接数组元素改变
    console.log(newArr); //=> [ [ 1 ], [ 2, 3 ] ] => 新数组发生改变
    arr[0].push(4); // 源数组元素改变
    console.log(newArr) //=> [ [ 1, 4 ], [ 2, 3 ] ] => 新数组发生改变
    newArr[0].push(5); // 新数组元素改变
    console.log(arr); //=> [ [ 1, 4, 5 ] ] => 对应源数组改变
}

entries

/*
* 作用:返回一个Array Iterator对象,包含数组中每个索引的键值对
* 语法:let [Iterator对象] = [数组].entries()
*   @params
*       无
*   @return
*       一个新的 Array 迭代器对象。Array Iterator是对象,它的原型(__proto__:Array Iterator)上有一个next方法,可用用于遍历迭代器取得原数组的[key,value]。
* */

// next()
{
    let arr = [1, 2, 3, 4, 5];
    let iterator = arr.entries();
    console.log(iterator);
    /*Array Iterator {}
         __proto__:Array Iterator
         next:ƒ next()
         Symbol(Symbol.toStringTag):"Array Iterator"
         __proto__:Object
    */
    console.dir(iterator.next()); //=> { value: [ 0, 1 ], done: false }
    console.dir(iterator.next()); //=> { value: [ 1, 2 ], done: false }
    console.dir(iterator.next()); //=> { value: [ 2, 3 ], done: false }
    console.dir(iterator.next()); //=> { value: [ 3, 4 ], done: false }
    console.dir(iterator.next()); //=> { value: [ 4, 5 ], done: false }
    console.dir(iterator.next()); //=> { value: undefined, done: true } => 直到迭代结束时,done才变成true
}

// for of循环
{
    let arr = [1, 2, 3, 4, 5];
    let iterator = arr.entries();
    for (let item of iterator) {
        console.log(item); //=> [0,1] => [1,2] => ...
    }
    console.dir(iterator.next()); //=> { value: undefined, done: true } => 循环结束相当于迭代结束
}

values

/*
* 作用:返回一个Array Iterator对象,包含数组中每个元素的值
* 语法:let [Iterator对象] = [数组].values()
*   @params
*       无
*   @return
*       包含数组每个元素值的类数组(Array Iterator)
* */

// next()
{
    let arr = [1, 2, 3, 4, 5];
    let iterator = arr.values();
    console.dir(iterator.next()); //=> { value: 1, done: false }
    console.dir(iterator.next()); //=> { value: 2, done: false }
    console.dir(iterator.next()); //=> { value: 3, done: false }
    console.dir(iterator.next()); //=> { value: 4, done: false }
    console.dir(iterator.next()); //=> { value: 5, done: false }
    console.dir(iterator.next()); //=> { value: undefined, done: true } => 直到迭代结束时,done才变成true
}

// for of循环
{
    let arr = [1, 2, 3, 4, 5];
    let iterator = arr.values();
    for (let item of iterator) {
        console.log(item); //=> 1 => 2 => ...
    }
    console.dir(iterator.next()); //=> { value: undefined, done: true } => 循环结束相当于迭代结束
}

every

/*
* 作用:测试数组内的元素,是否全部满足指定函数的规则
* 语法:let [Boolean] = [数组].every([cb([item],[index],[array])],[thisObj])
*   @params
*       cb:用于测试元素的函数,可接受三个参数
*           item:当前元素值
*           index:当前元素索引(可不写)
*           array:当前数组(可不写)
*       thisObj:执行cb时的this指向。如果不写,非严格模式下为window,严格模式下为undefined。
*   @return
*       true / false(函数每一次都返回true,则返回true,否则返回false)
* 注意:如果数组为空,则永远返回true;
* */
{
    let arr = [1, 2, 3, 4, 5];
    // 判断是否全部大于3
    let boolean = arr.every(function (item, index, array) {
        return item > 3;// 如果不写return,默认return false
    })
    console.log(boolean); //=> false
    //箭头函数
    boolean = arr.every(item => item > 3);
    console.log(boolean); //=> false
}

some

/*
* 作用:判断数组中是否至少有一个元素通过了指定函数的测试
* 语法:let [Boolean] = [原数组].some([cb([item],[index],[array]),[thisObj]])
*   @params
*       cb:用于测试元素的函数,可接受三个参数
*           item:当前元素值
*           index:当前元素索引(可不写)
*           array:当前数组(可不写)
*       thisObj:执行cb时的this指向。如果不写,非严格模式下为window,严格模式下为undefined。
*   @return
*       true / false
* 注意:若原数组是空数组,则在任何情况下都返回false
* */
{
    let arr = [1, 2, 3, 4];
    // 是否至少有一个数字大于5
    let boolean = arr.some(function (item, index, array) {
        return item > 5
    });
    console.log(boolean); //=> false
}

filter

/*
* 作用:创建一个新数组,包含满足指定函数的规则的元素
* 语法:let [新数组] = [原数组].filter([cb([item],[index],[array])],[thisObj])
*   @params
*       cb:用于测试元素的函数,可接受三个参数
*           item:当前元素值
*           index:当前元素索引(可不写)
*           array:当前数组(可不写)
*       thisObj:执行cb时的this指向。如果不写,非严格模式下为window,严格模式下为undefined。
*   @return
*       一个全新的,有满足指定函数的规则的元素组成的数组;如果没有任何元素通过测试,则返回空数组;
* */
{
    let arr = [1, 2, 3, 4, 5];
    // 取出大于3的值
    let newArr = arr.filter(function (item, index, array) {
        return item > 3;// 如果不写return,默认return false
    })
    console.log(newArr); //=> [ 4, 5 ]
    //箭头函数
    newArr = arr.filter(item => item > 3);
    console.log(newArr); //=> [ 4, 5 ]
}

find

/*
* 作用:返回数组中满足指定函数规则的第一个元素值
* 语法:let value = [原数组].find([value],[start],[end])
*   @params
*       cb:用于测试元素的函数,可接受三个参数
*           item:当前元素值
*           index:当前元素索引(可不写)
*           array:当前数组(可不写)
*       thisObj:执行cb时的this指向。如果不写,非严格模式下为window,严格模式下为undefined。
*   @return
*       数组中满足指定函数规则的第一个元素值;如果没有找到,返回undefined
* */
{
    let arr = [1, 2, 3, 4, 5];
    // 取出大于3的第一个值
    let value = arr.find(function (item, index, array) {
        return item > 3;// 如果不写return,默认return false
    })
    console.log(value); //=> 4
    //箭头函数
    value = arr.find(item => item > 3);
    console.log(value); //=> 4
}

findIndex

/*
* 作用:返回数组中满足指定函数规则的第一个元素索引
* 语法:let index = [原数组].findIndex([value],[start],[end])
*   @params
*       cb:用于测试元素的函数,可接受三个参数
*           item:当前元素值
*           index:当前元素索引(可不写)
*           array:当前数组(可不写)
*       thisObj:执行cb时的this指向。如果不写,非严格模式下为window,严格模式下为undefined。
*   @return
*       数组中满足指定函数规则的第一个元素索引;如果没有找到,返回-1
* */
{
    let arr = [1, 2, 3, 4, 5];
    // 取出大于3的第一个元素索引
    let index = arr.findIndex(function (item, index, array) {
        return item > 3;// 如果不写return,默认return false
    })
    console.log(index); //=> 3
    //箭头函数
    index = arr.findIndex(item => item > 3);
    console.log(index); //=> 3
}

indexOf

/*
* 作用:指定元素在数组中的第一个索引
* 语法:let index = [原数组].indexOf([value],[index])
*   @params
*       value:指定的值
*       index:索引,指定查找的起始位置。
*             如果不填,默认为0;
*             如果负数,则为数组长度+index;
*             如果计算出的索引为负值,则查找整个数组,相当于0;
*             如果大于数组长度,则直接返回-1;
*   @return
*       首个被找到的元素在数组中的索引位置; 若没有找到则返回-1。
* 注意:比较字符串和字符时会区分大小写。
* */
{
    let arr = [1, 2, 3];
    console.log(arr.indexOf(2)); //=> 1
    console.log(arr.indexOf(4)); //=> -1
    console.log(arr.indexOf(2, 2)); //=> -1
    console.log(arr.indexOf(3, -2)); //=> arr.indexOf(3, 1) => 2
    console.log(arr.indexOf(2, -100)); //=> arr.indexOf(2, 0) => 1
}

lastIndexOf

/*
* 作用:指定元素在数组中的最后一个索引
* 语法:let lastIndex = [原数组].lastIndexOf([value],[index])
*   @params
*       value:指定的值
*       index:索引,指定查找的起始位置。
*             如果不填,默认为数组长度-1;
*             如果负数,则为数组长度+index;
*             如果大于数组长度,则直接返回-1;
*   @return
*       指定元素在数组中的最后一个索引,若没有找到则返回-1
* */
{
    let arr = [1, 2, 3, 2];
    console.log(arr.lastIndexOf(2)); //=> 3
    console.log(arr.lastIndexOf(4)); //=> -1
    console.log(arr.lastIndexOf(2, 2)); //=> 1
    console.log(arr.lastIndexOf(3, -2)); //=> arr.indexOf(3, 1) => 2
    console.log(arr.lastIndexOf(2, -100)); //=> arr.indexOf(2, 0) => -1
}

forEach

/*
* 作用:遍历数组,对每个元素执行一次给定的函数。
* 语法:[原数组].forEach(cb([item],[index],[arr]),[thisObj])
*   @params
*       cb:自定义规则函数
*           item:当前元素值
*           index:当前元素索引
*           arr:当前数组
*       thisObj:执行cb时的this指向。如果不写,非严格模式下为window,严格模式下为undefined。
*   @return
*       undefined
* 注意:无法主动跳出循环,除非抛出异常。
* */
{
    let arr = [1, 2, 3];
    arr.forEach(function (item, index, arr) {
        console.log(item, index); //=> 1 0 => 2 1 => 3 2
    })
}

includes

/*
* 作用:判断数组中是否包含一个指定的值。
* 语法:[原数组].includes([value],[index])
*   @params
*       value:指定的值
*       index:索引,指定查找的起始位置。
*             如果不填,默认为0;
*             如果负数,则为数组长度+index;
*             如果计算出的索引为负值,则查找整个数组,相当于0;
*             如果大于数组长度,则直接返回false;
*   @return
*       true / false
* 注意:比较字符串和字符时会区分大小写。
* */
{
    let arr = [1, 2, 3];
    console.log(arr.includes(2)); // true
    console.log(arr.includes(4)); // false
    console.log(arr.includes(2, 2)); // false
    console.log(arr.includes(2, -100)); // true
}

join

/*
* 作用:将数组所有元素连接成一个字符串并返回。
* 语法:let str = [原数组].join([separator])
*   @params
*       separator:分隔符。
*                  如果不写,则默认是',';
*                  如果写"",则元素之间没有任何字符;
*   @return
*       一个所有数组元素连接的字符串。如果数组长度为0,则返回空字符串。
* 注意:如果数组只有一项,则直接返回该项,不使用分隔符;
*      如果元素是undefined或null,它会被转换为空字符串;
*      如果元素是对象,则先将对象toString(),再进行拼接;
* */
{
    let arr = [1, 2, 3];
    console.log(arr.join()); //=> 1,2,3
    arr = [{a: 1}, {b: 2}];
    console.log(arr.join()); //=> [object Object],[object Object]
    arr = [[1, 2], [3, 4]];
    console.log(arr.join()); //=> 1,2,3,4
}

keys

/*
* 作用:返回一个包含了数组中每个索引的类数组(Array Iterator)对象
* 语法:let iterator = [原数组].keys()
*   @params
*       无
*   @return
*       包含了数组中每个索引的类数组(Array Iterator)对象
* */
{
    let arr = [1, 2, 3];
    let iterator = [...arr.keys()];
    console.log(iterator); //=> [ 0, 1, 2 ]
}

map

/*
* 作用:遍历原数组,每个元素调用一次给定的函数后的返回值,合并成一个新数组
* 语法:let [新数组] = [原数组].map([cb([item],[index],[array])],[thisObj])
*   @params
*       cb:用于测试元素的函数,可接受三个参数
*           item:当前元素值
*           index:当前元素索引(可不写)
*           array:当前数组(可不写)
*       thisObj:执行cb时的this指向。如果不写,非严格模式下为window,严格模式下为undefined。
*   @return
*       一个全新的数组
* */
{
    let arr = [1, 2, 3, 4];
    // 元素每个值*2
    let newArr = arr.map(function (item, index, array) {
        return item * 2
    })
    console.log(arr, newArr); //=> [ 1, 2, 3, 4 ] [ 2, 4, 6, 8 ]
}

toString

/*
* 作用:将数组元素转为字符串,并且以逗号分隔
* 语法:let string = [原数组].toString()
*   @params
*      无
*   @return
*      转换后的字符串
* */
{
    let arr = [1, 2, 3, 4];
    let string = arr.toString();
    console.log(arr, string); //=> [ 1, 2, 3, 4 ] '1,2,3,4'
    console.log([{a: 1}, {a: 2}].toString()) //=> [object Object],[object Object]
}

flat

/*
* 作用:按照指定的"深度",递归遍历数组,将所有元素和遍历到的子数组中的元素合并为新的数组返回
* 语法:let index = [原数组].flat([deep])
*   @params
*       deep:指定遍历的深度,默认为1
*   @return
*       所有元素和遍历到的子数组中的元素合并的新数组
* */

// 扁平化数组
{
    let arr = [1, 2, [3, 4], 5];
    let newArr = arr.flat();
    console.log(arr, newArr); //=> [1, 2, [3, 4], 5] [1, 2, 3, 4, 5]
}

// 移除数组空项
{
    let arr = [1, 2, , 5];
    let newArr = arr.flat();
    console.log(arr, newArr); //=> [1, 2,, 5] [1, 2, 5]
}