解构赋值的一点理解和拓展

184 阅读2分钟
    let [...a] = [1,2,3] // a :[1, 2, 3]
    let [a] = [1,2,3] // a :1
    
    fn(1,2,3,4,4)
    function fn(){
      console.log(arguments);// [1, 2, 3, 4, 4, callee: ƒ, Symbol(Symbol.iterator): ƒ]
      console.log(Array.from(arguments)); // [1, 2, 3, 4, 4]
      console.log([...arguments]); // [1, 2, 3, 4, 4]
    }
    
    function fn2(...params) {
      console.log(params); // [1, 2, 3, 4, 4]
    }
    fn2(1, 2, 3, 4, 4)
    
    function fn3(params) {
      console.log(params); // 1
    }
    fn3(1, 2, 3, 4, 4)

Tips;arguments是数组内置的一个参数,这个参数是一个类数组Array-Like Object,它会自动把形参外面包一层[],所以它一定是个数组。对于函数中形参的解构赋值,解构的是这个类数组arguments。

类数组转数组的方法:

    **
    Array.from() // es6中
    Array.prototype.slice.apply()  // es5中
    [...arr]  //这个arr是个数组形式的
    **
    
    var obj = {
      0: "www",
      1: "jianshu",
      2: "com",
      length: 3
    };
    // slice类似这样的行为
    Array.prototype.slice = function (start, end) {
      var result = new Array();
      start = start || 0;
      console.log(this,'-'); // //this指向Array.prototype,当用了call后,能够改变this的指向,也就是指向传进来的对象,这是关键
      end = end || this.length;
      for (var i = start; i < end; i++) {
        result.push(this[i]);
      }
      return result;
    }
    // 方法1:
    console.log(Array.prototype.slice.apply(obj)); //["www","jianshu","com"]
    
    // 方法2:
    console.log(Array.from(obj)); //["www","jianshu","com"]
    
    // 方法3:
    console.log([...obj]); //报错:obj is not iterable,如果这个obj是数组中的arguments就可以

聊聊Object.create()这个静态方法,实例方法就是Object.prototype.xxx:

    var o1 = Object.create({
      x: 1,
      y: 2
    })

    var o2 = {};
    o2.__proto__ = {  // 对象都有这个__proto__指针,而prototype不一定有。
      x: 1,
      y: 2
    }

    console.log(o1, o2); // 打印结果如下图

image.png

    const o = Object.create({ x: 1, y: 2 });
    o.z = 3;

    let { x, ...newObj } = o;
    let { y, z } = newObj;
    x // 1
    y // undefined
    z // 3

Tips;由Object.create()创建的对象存在原型上,而解构赋值只能读取对象o自身的属性,所以y打印undefined

扩展运算符到底做了什么


    // 等同于 {...Object(1)}
    {...1} // {}

    // 等同于 {...Object(true)}
    {...true} // {}

    // 等同于 {...Object(undefined)}
    {...undefined} // {}

    // 等同于 {...Object(null)}
    {...null} // {}

再看看foo2的执行结果,实际默认执行了:Object()

    let foo = [
      ...['a', 'b', 'c']
    ];
    let foo1 = [
      ...Object(['a', 'b', 'c']) // 执行Object()强制转为对象
    ];
    let foo2 = {
      ...['a', 'b', 'c']
    };
    let foo3 = {
      ...Object(['a', 'b', 'c']) // 执行Object()强制转为对象
    };

    console.log(foo); // ['a', 'b', 'c']
    console.log(foo1); // ['a', 'b', 'c']
    console.log(foo2); // {0: 'a', 1: 'b', 2: 'c'}
    console.log(foo3); // {0: 'a', 1: 'b', 2: 'c'}

image.png 其实每个数组都可以展开的。