es6学习记录之数组扩展

113 阅读7分钟

es6学习记录之数组扩展

扩展运算符

说明:es6新增了数据运算符号,就像是rest参数的逆运算.可以将数组展开

    // 扩展运算符号基础展示
    let ad = [100,200,3,"张三"]
    let a = [...ad]
    console.log(a);//[100,200,3,"张三"]
    ad[2] = 5
    console.log(ad,a);//[100,200,3,"张三"],[100,200,5,"张三"]
    //浅拷贝 如果拷贝里面有复杂数据类型那么那个复杂数据类型修改会影响原数组

复制数组

        const a1 = [1, 2];
        // 写法一
        // const a2 = [...a1];
        // 写法二
        const [...a2] = a1;
        console.log(a2);//[1,2]
        //感觉第二钟写法还挺有意思的下面详细说一下

声明的时候使用扩展运算符就等于是一个rest参数,用的是剩余语法

    // 相当于
    let [ad,...ac] = [1,2,3,1,4]
    console.log(ad,ac);//1 , [2, 3, 1, 4]

个人感觉跟函数的rest参数很像都是收集剩余参数然后赋值给命名变量

注意!!!如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。

const [...one, last] = [1, 2, 3, 4, 5];
// 报错
const [two, ...twomiddle, twolast] = [1, 2, 3, 4, 5];
// 报错
const [first, ...middle] = [1, 2, 3, 4, 5];
//不报错

合并数组

        let ad = [1, 2, 3]
        let adc = [4, 5, 6]
        let cba =[...ad,...adc]
        console.log(cba);//[1, 2, 3, 4, 5, 6]

Array.prototype.sort() 的排序稳定性

首先了解一下sort函数的基本用法

// 升序
var arr = [3,2,3,34,12,23,234,84,9];
arr.sort(function (a, b) {
    return a - b;
});
// 结果:2,3,3,9,12,23,34,84,234

// 降序
var arr = [3,2,3,34,12,23,234,84,9];
arr.sort(function (a, b) {
    return b - a;
});
// 结果:234,84,34,23,12,9,3,3,2

具体可以看(javascript中sort()函数的理解 - 计算机科学的文章 - 知乎 zhuanlan.zhihu.com/p/22931269)

Array.from()

Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。

    let ad = {
        "0":18,
        "1":17,
        "2":1,  length: 4,多的一项为undefined
        length: 3 //不加这个长度就会返回空,加多了比如  length: 4,多的一项为undefined
    }
    let cd = Array.from(ad)
    console.log(cd); //[18, 17, 1]
    //length属性变成5
        let ad = {
        "0":18,
        "1":17,
        "2":1,
        length: 5
    }
    let cd = Array.from(ad)
    console.log(cd); //[18, 17, 1, undefined, undefined]

具体怎么使用还是不太了解感觉用的不多就不过多了解了

Array.of()

Array.of()将传入的参数转换为数组

    let arr = Array.of(1,2,3)
        console.log(arr);// [1, 2, 3]

这个方法主要是弥补Arrly构造函数不统一,参数的不同会使Arrly构造函数返回的结果不同

let one = new Array() //[]
let two = new Array(3) //[, , ,]
let three = new Array(3,2) //[3, 2]
//只有两个参数以上的话才会正常返回数据,什么都不写是空数组,只有一个参数只代表数组的长度

但是Arrly.of()方法很统一

let one = Array.of() //[]
let two = Array.of(1) //[1]
let three =  Array.of(3,2)//[3,2]

数组实例的 find() 和 findIndex()

find

find方法返回找到的第一个满足回调函数要求为true的值,都没找到返回undefined

        let tset = [1, 2, 3, 4, 5, 6, 7, 8]
        let ad = tset.find((item => {
            return item > 5
        }))
        console.log(ad);//6
        
        //find方法的回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组。
        [1, 5, 10, 15].find(function (value, index, arr) {
            return value > 9;
        }) // 10

findIndex

findIndex方法跟find差不多只不过返回的是索引

        let tset = [1, 2, 3, 1, 5, 6, 7, 8]
        let ad = tset.findIndex((item => {
            return item > 3
        }))
        console.log(ad);

这两个方法的第二个参数都可以绑定一个回调函数的this 对象

        function f(v) {
            return v > this.age;
        }
        let person = { name: 'John', age: 20 };
      console.log([10, 12, 26, 15].find(f, person));    // 26
      //上面的代码中,`find`函数接收了第二个参数`person`对象,回调函数中的`this`对象指向`person`对象。

数组实例的 fill()

fill()方法 fill翻译了一下填满填充,就是将原数组中的所有数据替换成传入的参数,只接收一个参数就是全部填充

       let  ad = [1,2,3,4,5,6,7,8,9]
       console.log(ad.fill(7));//[7, 7, 7, 7, 7, 7, 7, 7, 7]

第二个第三个参数决定填充的起始位置和结束位置

    let  ad = [1,2,3,4,5,6,7,8,9]
       console.log(ad.fill(7,0,8));// [7, 7, 7, 7, 7, 7, 7, 7, 9]
       //从第0个开始第八个结束

注意,如果填充的类型为对象,那么被赋值的是同一个内存地址的对象,而不是深拷贝对象。

        let arr = new Array(3).fill({ name: "Mike" });
        arr[0].name = "Ben";
        console.log(arr);// [{name: "Ben"}, {name: "Ben"}, {name: "Ben"}]
        let arr = new Array(3).fill([]);
        arr[0].push(5);  //这里只push了一个结果全改了
        console.log(arr); // [[5], [5], [5]]

数组实例的 entries(),keys() 和 values()

ES6 提供三个新的方法——entries()keys()values()——用于遍历数组。它们都返回一个遍历器对象(详见《Iterator》一章),可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。

  for (let index of ['a', 'b'].keys()) {
            console.log(index);
        }
        // 0
        // 1
        for (let elem of ['a', 'b'].values()) {
            console.log(elem);
        }
        // 'a'
        // 'b'
        for (let [index, elem] of ['a', 'b'].entries()) {
            console.log(index, elem);
        }
        // 0 "a"
        // 1 "b"

数组实例的 includes()

Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。ES2016 引入了该方法。

        [1, 2, 3].includes(2)     // true
        [1, 2, 3].includes(4)     // false
        [1, 2, NaN].includes(NaN) // true

该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。

      [1, 2, 3].includes(3, 3);  // false
      [1, 2, 3].includes(3, -1); // true

没有该方法之前,我们通常使用数组的indexOf方法,检查是否包含某个值。但是indexOf方法有两个缺点,一是不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于-1,表达起来不够直观。二是,它内部使用严格相等运算符(===)进行判断,这会导致对NaN的误判。includes使用的是不一样的判断算法,就没有这个问题。

      if (arr.indexOf(el) !== -1) {
            // ...
        }

另外,Map 和 Set 数据结构有一个has方法,需要注意与includes区分。

  • Map 结构的has方法,是用来查找键名的,比如Map.prototype.has(key)WeakMap.prototype.has(key)Reflect.has(target, propertyKey)
  • Set 结构的has方法,是用来查找值的,比如Set.prototype.has(value)WeakSet.prototype.has(value)

数组实例的 flat(),flatMap()

Array.prototype.flat()

数组的成员有时还是数组,Array.prototype.flat()用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响。

 [1, 2, [3, 4]].flat()
// [1, 2, 3, 4]
//上面代码中,原数组的成员里面有一个数组,`flat()`方法将子数组的成员取出来,添加在原来的位置。

如果不管是多少层都要拉平提供Infinity关键字

[1, [2, [3]]].flat(Infinity)
// [1, 2, 3]

如果原数组有空位,flat()方法会跳过空位。

[1, 2, , 4, 5].flat()
// [1, 2, 4, 5]

Array.prototype.flatMap()

flatMap()方法对原数组的每个成员执行一个函数(相当于执行Array.prototype.map()),然后对返回值组成的数组执行flat()方法。该方法返回一个新数组,不改变原数组。

// 相当于 [[2, 4], [3, 6], [4, 8]].flat()
[2, 3, 4].flatMap((x) => [x, x * 2])
// [2, 4, 3, 6, 4, 8]

参考资料:阮一峰 ECMAScript 6 (ES6) 标准入门教程 第三版