# 对象的扩展

  1. 属性和方法简写
// 允许写入变量和函数,作为对象的属性和方法
const foo='str'
const obj={
    get(){
        console.log(1)
    },
    name,//name:name
    foo//foo:'str'
}
  1. 属性名表达式
let key1 = 'foo';
let obj = {
  [key1]: true,
  ['a' + 'b']: 123
}
//属性名表达式与简洁表示法,不能同时使用
const foo = 'bar'
const bar = 'abc'
const baz = { [foo] };//报错
  1. name属性
function foo(){
    console.log('hello')
}
foo.name//foo
//2个特殊情况
//1.bind方法创造的函数,name属性返回bound加上原函数的名字
//Function构造函数创造的函数,name属性返回anonymous
  1. Object.is()
    比较两个值是否严格相等
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
  1. Object.assign()
    用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
Object.assign(target, source1, source2);
//参数不是对象,则会先转成对象,然后返回。
//undefined和null无法转成对象,如果它们作为参数,就会报错。
//拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性)
//也不拷贝不可枚举的属性(enumerable: false)。
//浅拷贝,目标对象拷贝得到的是这个对象的引用。

常见用途 - 对象添加属性 - 对象添加方法 - 克隆对象 - 合并多个对象 - 属性指定默认值

const DEFAULTS = {//默认值
  level: 0,
  name: 'str'
};
function processContent(options) {
  options = Object.assign({}, DEFAULTS, options);
  console.log(options);
}
  1. 可枚举性和遍历
  • 可枚举性
//属性都有一个描述对象(Descriptor),用来控制该属性的行为
let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
//  {
//    value: 123,
//    writable: true,//可读
//    enumerable: true,//可枚举
//    configurable: true//可删除
//  }
//4个操作会忽略enumerable为false的属性
//1.for...in
//2. Object.keys()
//3.JSON.stringify()
//4. Object.assign()
//所有Class 的原型的方法都是不可枚举的。
//尽量不要用for...in循环,而用Object.keys()代替。
  • 遍历
    1. for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。
    2. Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。
    3. Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。
    4. Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。
    5. Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
  1. _proto_
    __proto__调用的是Object.prototype.__proto__

  2. super
    指向当前对象的原型对象。

  3. Object.keys(),values(),entries()

  • Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。
  • Object.values方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。
    如果参数不是对象,Object.values会先将其转为对象。由于数值和布尔值的包装对象,都不会为实例添加非继承的属性。所以,Object.values会返回空数组。
  • Object.entries方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。
  1. 扩展运算符
let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }等同于Object.assign
let ab = { ...a, ...b };//合并对象
let { ...x } = z;