美文网首页
【ES6】数组新增方法

【ES6】数组新增方法

作者: Daeeman | 来源:发表于2020-03-20 15:42 被阅读0次

    7 数组的拓展

    #7.1 拓展运算符

    拓展运算符使用(...),类似rest参数的逆运算,将数组转为用(,)分隔的参数序列。

    console.log(...[1, 2, 3]);   // 1 2 3 
    console.log(1, ...[2,3], 4); // 1 2 3 4
    
    

    拓展运算符主要使用在函数调用。

    function f (a, b){
        console.log(a, b);
    }
    f(...[1, 2]); // 1 2
    
    function g (a, b, c, d, e){
        console.log(a, b, c, d, e);
    }
    g(0, ...[1, 2], 3, ...[4]); // 0 1 2 3 4
    
    

    若拓展运算符后面是个空数组,则不产生效果

    [...[], 1]; // [1]
    
    

    替代apply方法

    // ES6之前
    function f(a, b, c){...};
    var a = [1, 2, 3];
    f.apply(null, a);
    
    // ES6之后
    function f(a, b, c){...};
    let a = [1, 2, 3];
    f(...a);
    
    // ES6之前
    Math.max.apply(null, [3,2,6]);
    
    // ES6之后
    Math.max(...[3,2,6]);
    
    

    拓展运算符的运用

    • (1)复制数组
      通常我们直接复制数组时,只是浅拷贝,如果要实现深拷贝,可以使用拓展运算符。
    // 通常情况 浅拷贝
    let a1 = [1, 2];
    let a2 = a1; 
    a2[0] = 3;
    console.log(a1,a2); // [3,2] [3,2]
    
    // 拓展运算符 深拷贝
    let a1 = [1, 2];
    let a2 = [...a1];
    // let [...a2] = a1; // 作用相同
    a2[0] = 3;
    console.log(a1,a2); // [1,2] [3,2]
    
    
    • (2)合并数组
      注意,这里合并数组,只是浅拷贝。
    let a1 = [1,2];
    let a2 = [3];
    let a3 = [4,5];
    
    // ES5 
    let a4 = a1.concat(a2, a3);
    
    // ES6
    let a5 = [...a1, ...a2, ...a3];
    
    a4[0] === a1[0]; // true
    a5[0] === a1[0]; // true
    
    
    • (3)与解构赋值结合
      与解构赋值结合生成数组,但是使用拓展运算符需要放到参数最后一个,否则报错。
    let [a, ...b] = [1, 2, 3, 4]; 
    // a => 1  b => [2,3,4]
    
    let [a, ...b] = [];
    // a => undefined b => []
    
    let [a, ...b] = ["abc"];
    // a => "abc"  b => []
    
    

    #7.2 Array.from()

    类数组对象可遍历的对象,转换成真正的数组。

    // 类数组对象
    let a = {
        '0':'a',
        '1':'b',
        length:2
    }
    let arr = Array.from(a);
    
    // 可遍历的对象
    let a = Array.from([1,2,3]);
    let b = Array.from({length: 3});
    let c = Array.from([1,2,3]).map(x => x * x);
    let d = Array.from([1,2,3].map(x => x * x));
    
    

    #7.3 Array.of()

    将一组数值,转换成数组,弥补Array方法参数不同导致的差异。

    Array.of(1,2,3);    // [1,2,3]
    Array.of(1).length; // 1
    
    Array();       // []
    Array(2);      // [,] 1个参数时,为指定数组长度
    Array(1,2,3);  // [1,2,3] 多于2个参数,组成新数组
    
    

    #7.4 find()和findIndex()

    find()方法用于找出第一个符合条件的数组成员,参数为一个回调函数,所有成员依次执行该回调函数,返回第一个返回值为true的成员,如果没有一个符合则返回undefined

    [1,2,3,4,5].find( a => a < 3 ); // 1
    
    

    回调函数接收三个参数,当前值、当前位置和原数组。

    [1,2,3,4,5].find((value, index, arr) => {
        // ...
    });
    
    

    findIndex()方法与find()类似,返回第一个符合条件的数组成员的位置,如果都不符合则返回-1

    [1,2,3,4].findIndex((v,i,a)=>{
        return v>2;
    }); // 2
    
    

    #7.5 fill()

    用于用指定值填充一个数组,通常用来初始化空数组,并抹去数组中已有的元素。

    new Array(3).fill('a');   // ['a','a','a']
    [1,2,3].fill('a');        // ['a','a','a']
    
    

    并且fill()的第二个和第三个参数指定填充的起始位置结束位置

    [1,2,3].fill('a',1,2);
    
    

    #7.6 entries(),keys(),values()

    主要用于遍历数组,entries()对键值对遍历,keys()对键名遍历,values()对键值遍历。

    for (let i of ['a', 'b'].keys()){
        console.log(i)
    }
    // 0
    // 1
    
    for (let e of ['a', 'b'].values()){
        console.log(e)
    }
    // 'a'
    // 'b'
    
    for (let e of ['a', 'b'].entries()){
        console.log(e)
    }
    // 0 'a'
    // 1 'b'
    
    

    #7.7 includes()

    用于表示数组是否包含给定的值,与字符串的includes方法类似。

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

    第二个参数为起始位置,默认为0,如果负数,则表示倒数的位置,如果大于数组长度,则重置为0开始。

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

    #7.8 flat(),flatMap()

    flat()用于将数组一维化,返回一个新数组,不影响原数组。
    默认一次只一维化一层数组,若需多层,则传入一个整数参数指定层数。
    若要一维化所有层的数组,则传入Infinity作为参数。

    [1, 2, [2,3]].flat();        // [1,2,2,3]
    [1,2,[3,[4,[5,6]]]].flat(3); // [1,2,3,4,5,6]
    [1,2,[3,[4,[5,6]]]].flat('Infinity'); // [1,2,3,4,5,6]
    
    

    flatMap()是将原数组每个对象先执行一个函数,在对返回值组成的数组执行flat()方法,返回一个新数组,不改变原数组。
    flatMap()只能展开一层。

    [2, 3, 4].flatMap((x) => [x, x * 2]); 
    // [2, 4, 3, 6, 4, 8] 
    

    8 对象的拓展

    #8.1 属性的简洁表示

    let a = 'a1';
    let b = { a };  // b => { a : 'a1' }
    // 等同于
    let b = { a : a };
    
    function f(a, b){
        return {a, b}; 
    }
    // 等同于
    function f (a, b){
        return {a:a ,b:b};
    }
    
    let a = {
        fun () {
            return 'leo';
        }
    }
    // 等同于
    let a = {
        fun : function(){
            return 'leo';
        }
    }
    
    

    #8.2 属性名表达式

    JavaScript提供2种方法定义对象的属性

    // 方法1 标识符作为属性名
    a.f = true;
    
    // 方法2 字符串作为属性名
    a['f' + 'un'] = true;
    
    

    延伸出来的还有:

    let a = 'hi leo';
    let b = {
        [a]: true,
        ['a'+'bc']: 123,
        ['my' + 'fun'] (){
            return 'hi';
        }
    };
    // b.a => undefined ; b.abc => 123 ; b.myfun() => 'hi'
    // b[a] => true ; b['abc'] => 123 ; b['myfun'] => ƒ ['my' + 'fun'] (){ return 'hi'; }
    
    

    注意
    属性名表达式不能与简洁表示法同时使用,否则报错。

    // 报错
    let a1 = 'aa';
    let a2 = 'bb';
    let b1 = {[a1]};
    
    // 正确
    let a1 = 'aa';
    let b1 = { [a1] : 'bb'};
    
    

    #8.3 Object.is()

    Object.is() 用于比较两个值是否严格相等,在ES5时候只要使用相等运算符(==)和严格相等运算符(===)就可以做比较,但是它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0

    Object.is('a','a');   // true
    Object.is({}, {});    // false
    
    // ES5
    +0 === -0 ;           // true
    NaN === NaN;          // false
    
    // ES6
    Object.is(+0,-0);     // false
    Object.is(NaN,NaN);   // true
    
    

    #8.4 Object.assign()

    Object.assign()方法用于对象的合并,将原对象的所有可枚举属性复制到目标对象。
    基础用法
    第一个参数是目标对象,后面参数都是源对象

    let a = {a:1};
    let b = {b:2};
    Object.assign(a,b);  // a=> {a:1,b:2}
    
    

    注意

    • 若目标对象与源对象有同名属性,则后面属性会覆盖前面属性。
    let a = {a:1, b:2};
    let b = {b:3, c:4};
    Object.assign(a, b); // a => {a:1, b:3, c:4}
    
    
    • 若只有一个参数,则返回该参数。
    let a = {a:1};
    Object.assign(a) === a;  // true
    
    
    • 若参数不是对象,则先转成对象后返回。
    typeof Object.assign(2); // 'object'
    
    
    • 由于undefinedNaN无法转成对象,所以做为参数会报错。
    Object.assign(undefined) // 报错
    Object.assign(NaN);      // 报错
    
    
    • Object.assign()实现的是浅拷贝。

    Object.assign()拷贝得到的是这个对象的引用。这个对象的任何变化,都会反映到目标对象上面。

    let a = {a: {b:1}};
    let b = Object.assign({},a);
    a.a.b = 2;
    console.log(b.a.b);  // 2
    
    
    • 将数组当做对象处理,键名为数组下标,键值为数组下标对应的值。
    Object.assign([1, 2, 3], [4, 5]); // [4, 5, 3]
    

    相关文章

      网友评论

          本文标题:【ES6】数组新增方法

          本文链接:https://www.haomeiwen.com/subject/tivjyhtx.html