ES6对象的扩展(一)

164 阅读2分钟

对象的写法

  • 对象属性的简写, 属性名与变量名相同 可以简写为一下代码。

    let foo = 'bar';
    const obj = {
       foo
    }
    console.log(obj.foo); // -> bar
    
    function bar (a, b) {
      console.log({a, b}); // -> {a: 1, b: 2}
    }
    foo(1, 2);
    
  • 对象方法的简写

    let age = 22;
    const person = {
      age,
      say(){
        console.log(this.age);
      }
    }
    person.say(); // -> 22
    
  • 对象的属性名都会默认调用自身原型上的toString()转换为字符串。

    let a = 'hello',
        b = 'world';
    let obj = {
      [a + b]: true,
      [a + 'world']: false,
      ['hello' + b]: undefined
    }
    console.log(obj); // -> {helloworld: undefined}
    
    let myObj = {};
    myObj[true] = 1;
    myObj[3] = 2;
    myObj[myObj] = 3;
    // 属性名为对象时,会调用Object.prototype.toString() -> '[object Object]'
    console.log(myObj); // -> {3: 2, true: 1, [object Object]: 3}
    
    // 经典面试题
    const a = {a: 1},
          b = {b: 2};
    const obj = {
       [a]: 'valueA',
       [b]: 'valueB'
    }
    console.log(obj); // -> {[object Object]: "valueB"}
    

属性描述符

  • 对象的构造器上新增的方法Object.getOwnPropertyDescriptor(),方法接收两个参数,第一个参数要获取描述的对象,第二个要获取描述对象的属性。返回值是一个对象,对象内有四个属性,value属性的值;enumerable属性是否可枚举;writable属性是否可改写;configurable属性是否可配置。与其对应的一个方法Object.defineProperty(),为对象设置属性(修改一个已有的属性或添加一个新属性)。

    let obj = {
      b: 3
    };
    // 通过 Object.defineProperty()定义的属性,除了value其他属性不配置默认为false
    Object.defineProperty(obj, 'a', {
      value: 2,
      enumerable: true,
      configurable: true
    });
    
    console.log(Object.getOwnPropertyDescriptor(obj, 'a'));
    // -> {value: 2, writable: false, enumerable: true, configurable: true}
    console.log(Object.getOwnPropertyDescriptor(obj, 'b'));
    // -> {value: 3, writable: true, enumerable: true, configurable: true}
    
    obj.a = 1;   // 注意:在严格模式下会报错
    console.log(obj.a); // -> 2 // 静默失败 因为他的 writable  false 
    
    delete obj.a // 是可以删除的 如果不想被删除 必须 configurable 的值也为 false
    
  • getter & setter 改写内部默认操作

    let obj = {
      a: 1
    };
    obj.a;  // 属性的获取 内部默认 [[Get]]操作:查找当前属性,如果没有去原型查找
    obj.a = 2;  // 属性的赋值 内部默认 [[Put]]操作: 
                      1. 看看是否有getter、setter; 
                      2. writable 属性是否为false 如果为false 则不能修改;
                      3. 赋值;
    // getter
    let cars = {
      brand: ['Benz', 'Toyota'],
      get laster() {
        if(this.brand.length === 0){
          return undefined;
        }
        return this.brand[this.brand.length - 1];
      }
    }
    console.log(cars.laster); // -> Toyota
    // 也可以通过这种方式来定义
    Object.defineProperty(cars, 'first',{
      get (){
        return this.brand[0];
      },
      enumerable: true
      // 注意:value、writable 属性就不可用 写了就会报错
    });
    console.log(cars.first); // -> Benz
    
    // setter
    let language = {
      lang: [],
      set curLang (val) {
        this.lang.push(val);
      }
    };
    language.curLang = 'CN';
    language.curLang = 'EN';
    console.log(language.lang); // -> ["CN", "EN"]
    
    // 因为getter、setter覆盖了原本默认的[[Get]][[Put]]操作,所以一般都会成对出现
    let num = {  
      get a () {
        return this._a === undefined ? 3 : this._a;  
      },  
      set a (val) {
        return this._a = val; 
      }
    }
    console.log(num.a); // -> 3
    num.a = 4;
    console.log(num.a); // -> 4