ES6总结(三)

1. 对象的扩展

  1. 新的对象字面量特征:
    a. 方法的定义:
    如:
    1
    2
    3
    4
    5
    6
    7
    let obj = {
    a: 1,
    show(){ // 把中间的冒号和function省略了
    console.log('show');
    }
    };
    obj.show(); // show
    b. 属性的简写
    如:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    let name = 'dai';
    let obj = {
    name: name
    };
    // 上面的obj对象中的name属性可以简写成下面这种写法
    let name = 'dai';
    let obj = {
    name // 只要形式一样就可以简写
    };
    c. 计算属性名
    如:
    1
    2
    3
    4
    5
    6
    7
    8
    let a = "name";
    let obj = {
    // []里面不仅可以写字符串,还可以写变量或者表达式。
    // 如将其改为[a + '1']: 1,最后打印出来为{name1: 1,b: 2}
    [a]: 1,
    b: 2
    };
    console.log(obj); // {name: 1,b: 2}
  2. 新的对象方法
    a. Object.is()方法用来判断两个值是否相等。多用于科学计算、精确计算。
    如:
    1
    2
    3
    4
    Object.is(1,1); // true,表明1和1是否相等
    Object.is(1,'1'); // false
    Object.is(NaN,NaN); // true,这里需要注意一下NaN和NaN判断出来为true
    Object.is(-0,+0); // false,在这里也需要注意一下
  3. Object.setPrototypeOf
    Object.setPrototypeOf()可以设置一个对象的原型,可以给一个对象赋予新的原型。
    如:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let obj = {a: 1,b: 2};
    let obj1 = {c: 3};
    // 方法一:
    Object.setPrototypeOf(obj,obj1); // 表明把obj的原型设置为obj1
    console.log(obj.c); // 3,它的作用是检验原型设置上没有
    // 方法二:
    obj._proto_ = obj1; // 由于_proto_是内置属性,不想让我们去使用
    // 方法三:
    let obj2 = Object.create(obj); // 它的作用是把obj2的原型设置为obj
    console.log(obj2.a); // 1
    在这里我们需要注意:ES5里面就有了Object.getPrototypeOf()表示获取一个原型;一定不要去使用_proto_内置属性,这样做是不好的。
  4. Object.assign()的使用场景
    a. 对象的复制;
    b. 原型方法的添加:
    如:
    1
    2
    3
    4
    5
    6
    7
    function Person(){
    this.name = "dai";
    }
    Object.assign(Person.prototype,{ // Person.prototype本来就是对象,所以它就可以放在这里
    eat(){},
    walk(){}
    });
    c. 函数默认参数:
    如:
    1
    2
    3
    4
    5
    const DEFAULTS = {a: 1,b: 2};
    function fn(options){
    let realOptions = Object.assign({},DEFAULTS,options);
    }
    fn({a: 2});
  5. 对象的遍历
    a. Object.keys表示对象的属性名;
    b. Object.values表示对象的属性值(es2017);
    c. Object.entries表示所有对象的键值对(es2017)。
  6. Object.assign()可以合并对象(返回值是目标对象的值)
    如:
    1
    2
    3
    4
    5
    6
    let obj1 = {a: 1};
    let obj2 = {b: 2};
    let obj3 = {c: 3};
    // 下面这行代码表示把obj2身上的所有属性和obj3身上的所有属性全部复制到目标对象obj1上面
    Object.assign(obj1,obj2,obj3); // obj1是目标对象,obj2和obj3是合并对象,可以有多个
    console.log(obj1); // {a: 1,b: 2,c: 3}

注意:

  1. 复制对象属性,自身的可遍历的属性才可以复制到目标对象上面(如果它原型上有属性,是不会复制到目标对象上面的)。
    如:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    let obj1 = {a: 1};
    let obj2 = {b: 2};
    let obj3 = {c: 3};
    let obj4 = {d: 4};
    Object.setPrototypeOf(obj2,obj4);
    console.log(obj2.d); // 4
    // 此时这里是没有d:4。因为obj2自身上没有d:4这个属性,只是它原型
    Object.assign(obj1,obj2,obj3);
    console.log(obj1); // {a: 1,b: 2,c: 3}
  2. 如果属性是不可遍历的,是不会复制到目标对象上面的。
    如:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    let obj1 = {a: 1};
    let obj2 = {b: 2};
    let obj3 = {c: 3};
    let obj4 = {d: 4};
    Object.setPrototypeOf(obj2,obj4);
    Object.defineProperty(obbj2,"e",{
    value: 5,
    enumerable: false // 如果将这里改为true的话,打印obj1得到的是{a: 1,b: 2,e: 5,c: 3}
    });
    console.log(obj2.e);
    Object.assign(obj1,obj2,obj3);
    console.log(obj1); // {a: 1,b: 2,c: 3},为什么在这里没有e:5,是因为在enumerable: false设置为不可遍历
  3. 复制是一个对象一个对象复制的。
    如:
    1
    2
    3
    4
    5
    6
    7
    let obj1 = {a: 1};
    let obj2 = {b: 2};
    let obj3 = {b: 3};
    Object.assign(obj1,obj2,obj3);
    // 因为复制是一个对象一个对象复制的,obj2先复制到obj1上面,然后obj3再复制到obj1上面,
    // 此时obj3中的b属性会把obj2中的b属性给覆盖掉
    console.log(obj1); // {a: 1,b: 3}