对象的扩展

1.对象的简写:

const foo = 'bar';
const baz = {foo};
baz // {foo: "bar"}

// 等同于
const baz = {foo: foo};

2.简写法:打印对象

let user = {
  name: 'test'
};

let foo = {
  bar: 'baz'
};

console.log(user, foo)
// {name: "test"} {bar: "baz"}
console.log({user, foo})
// {user: {name: "test"}, foo: {bar: "baz"}}

console.log直接输出userfoo两个对象时,就是两组键值对,可能会混淆。把它们放在大括号里面输出,就变成了对象的简洁表示法,每组键值对前面会打印对象名,这样就比较清晰了。

3.属性名的表达式:

  表达式作为属性名,表达式需要放在方括号内。

  若属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[object Object]

  所以,如果在同一个对象里有多个为对象的属性名,如[keyA]和[keyB]得到的都是[object Object],[keyB]会把[keyA]覆盖掉,而最后只有一个[object Object]属性。

4.属性的可枚举性和遍历

对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。

let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
//  {
//    value: 123,
//    writable: true,
//    enumerable: true,
//    configurable: true
//  }

描述对象的enumerable属性,称为“可枚举性”,如果该属性为false,就表示某些操作会忽略当前属性。

目前,有四个操作会忽略enumerablefalse的属性。

  • for...in循环:只遍历对象自身的和继承的可枚举的属性。
  • Object.keys():返回对象自身的所有可枚举的属性的键名。
  • JSON.stringify():只串行化对象自身的可枚举的属性。
  • Object.assign(): 忽略enumerablefalse的属性,只拷贝对象自身的可枚举的属性。

这四个操作之中,前三个是 ES5 就有的,最后一个Object.assign()是 ES6 新增的。其中,只有for...in会返回继承的属性,其他三个方法都会忽略继承的属性,只处理对象自身的属性。实际上,引入“可枚举”(enumerable)这个概念的最初目的,就是让某些属性可以规避掉for...in操作,不然所有内部属性和方法都会被遍历到。比如,对象原型的toString方法,以及数组的length属性,就通过“可枚举性”,从而避免被for...in遍历到。

属性的遍历

ES6一共有5种方法可以遍历对象的属性。

(1)for...in

         for...in循环遍历对象自身的和继承的可枚举属性(不含Symbol属性)。

 (2)Object.keys(obj)

         Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不 含Symbol属性)的键名。

  (3)Object.getOwnPrototypeNames(obj)

          Object.getOwnPrototypeNames返回一个数组,包含对象自身的所有属性(不含Symbol属性,但是包括不可枚举属性)的键名。

   (4) Object.getOwnPropertySymbols(obj)

     Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。

    (5)Reflect.ownKeys(obj)

      Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。

以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。

  • 首先遍历所有数值键,按照数值升序排列。
  • 其次遍历所有字符串键,按照加入时间升序排列。
  • 最后遍历所有 Symbol 键,按照加入时间升序排列。
原文地址:https://www.cnblogs.com/psxiao/p/11489132.html