ES6对象扩展(三)

165 阅读2分钟

keys、values、entries

  • 对象构造器Object上的方法,遍历对象自身可枚举属性的keys键名、 values 键值、 entries 键名键值组成的数组。

    const foo = {
      a: 1
    }
    Object.defineProperties(foo, {
      b: {
        value: 2,
        enumerable: true
      },
      c: {
        value: 3,
        enumerable: false
      }
    })
    
    console.log(Object.keys(foo)); // -> ['a', 'b']
    console.log(Object.values(foo)); // -> [1, 2]
    console.log(Object.entries(foo)); // -> [['a', 1], ['b', 2]]
    

Symbol

  • 新增的一个原始类型值,创建一个独一无二的值。Symbol()不可以 new 执行 。可以转换为字符串类型和布尔值类型,数字类型不能转换。

    let s1 = Symbol();
    let s2 = Symbol();
    console.log(s1, s2); // -> Symbol() Symbol()
    console.log(s1 === s2); // -> false
    
    // 转字符串 可以通过自身原型上的toString()方法 或 String() 
    console.log(s1.toString()); // -> 'Symbol()'
    console.log(String(s1)); // -> 'Symbol()'
    console.log(s1 + ''); // -> 报错 不可以通过隐式转换来转字符串
    
    // 转布尔值
    console.log(Boolean(s1)); // -> true
    console.log(!s1); // -> false 转布尔类型 可以通过隐式转换
    
    // 不可以转数字类型
    console.log(Number(s1)); // -> TypeError: Cannot convert a Symbol value to a number
    
  • 那么它有什么用呢? 一般用于对象属性名,但是只能同过对象[]的方式来定义属性名,因为.操作符内部默认会转换为字符串。for in 不能遍历Symbol类型的属性。只能通过Object.getOwnPropertySymbols() 来遍历Symbol类型的属性, 返回值是一个数组。

    let name = Symbol('name');
    let person = {
      age: 22
    };
    person[name] = 'zhangsan';
    console.log(person[name]); // -> zhangsan
    
    for(let key in person){
      console.log(key); // -> age
    }
    
    Object.getOwnPropertySymbols(person); // -> [Symbol(name)]
    
  • 可以传一个标识符,Symbol.for(),内部可以通过传入的标识符(key)取到同一个值。Symbol.keyFor(),可以获取当前传入的标识符(key)的值。

    let s = Symbol('bar');
    let s1 = Symbol.for('bar');
    let s2 = Symbol.for('bar');
    
    console.log(s === s1); // -> false
    console.log(s1 === s2); // -> true
    
    console.log(Symbol.keyFor(s)); // -> undefined
    console.log(Symbol.keyFor(s1)); // -> bar
    

遍历方法总结

  • for in 遍历对象自身和原型上可枚举属性(不包含Symbol类型属性)

  • Object.keys() 遍历自身可枚举的属性(不包含Symbol类型属性)

  • Object.getOwnPropertySymbols() 遍历自身 Symbol 类型的属性,无论是否可枚举

  • Object.assign() 拷贝的是自身可枚举的属性(包含Symbol类型属性)

    const obj = {
      a: 1,
      b: 2
    }
    
    let c = Symbol('c'),
        d = Symbol('d'),
        _c = Symbol('_c'),
        _d = Symbol('_d');
    
    obj[c] = 3;
    obj[d] = 4;
    
    Object.defineProperties(obj, {
      e: {
        value: 5,
        enumerable: true
      },
      f: {
        value: 6,
        enumerable: false
      },
      [_c]: {
        value: -3,
        enumerable: true
      },
      [_d]: {
        value: -4,
        enumerable: false
      }
    })
    
    let h = Symbol('h'),
        i = Symbol('i'),
        j = Symbol('j');
    
    const proto = {
      g: 7,
      [h]: 8
    }
    
    Object.defineProperties(proto, {
      [i]: {
        value: 9,
        enumerable: true
      },
      [j]: {
        value: 10,
        enumerable: false
      },
      k: {
        value: 11,
        enumerable: false
      }
    })
    
    Object.setPrototypeOf(obj, proto);
    console.log(obj);
    
    for(let key in obj){
      console.log(key); // -> a b e g
    }
    
    console.log(Object.keys(obj)); // -> ['a', 'b', 'e']
    
    Object.getOwnPropertySymbols(obj); // -> [Symbol(c), Symbol(d), Symbol(_c), Symbol(_d)]
    
    let copy = Object.assign({}, obj);
    console.log(copy); // -> {a: 1, b: 2, e: 5, Symbol(c): 3, Symbol(d): 4, Symbol(_c): -3}