Skip to content

对象拓展

属性的简洁表示

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

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

属性名表达式

javascript
obj.foo = true;
obj['a' + 'bc'] = 123;

let lastWord = 'last word';
const a = {
  'first word': 'hello',
  [lastWord]: 'world'
};
obj.foo = true;
obj['a' + 'bc'] = 123;

let lastWord = 'last word';
const a = {
  'first word': 'hello',
  [lastWord]: 'world'
};

注意

属性名表达式简洁表示法,不能同时使用,会报错。

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

对象方法 name 属性

  • 函数的name属性,返回函数名。对象方法也是函数,因此也有name属性。
  • 如果对象的方法使用了取值函数(getter)和存值函数(setter),则name属性不是在该方法上面,而是该方法的属性的描述对象的get和set属性上面,返回值是方法名前加上get和set。
  • 如果对象的方法是一个 Symbol 值,那么name属性返回的是这个 Symbol 值的描述。
javascript
const person = {
  sayName() {
    console.log('hello!');
  },
};
person.sayName.name   // "sayName"

const obj = {
  get foo() {},
  set foo(x) {}
};
const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo');
descriptor.get.name // "get foo"

const key1 = Symbol('description');
const key2 = Symbol();
let obj = {
  [key1]() {},
  [key2]() {},
};
obj[key1].name // "[description]"
obj[key2].name // ""
const person = {
  sayName() {
    console.log('hello!');
  },
};
person.sayName.name   // "sayName"

const obj = {
  get foo() {},
  set foo(x) {}
};
const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo');
descriptor.get.name // "get foo"

const key1 = Symbol('description');
const key2 = Symbol();
let obj = {
  [key1]() {},
  [key2]() {},
};
obj[key1].name // "[description]"
obj[key2].name // ""

对象属性的可枚举性和遍历

ES6 规定,所有 Class 的原型的方法都是不可枚举的

javascript
Object.getOwnPropertyDescriptor(class {foo() {}}.prototype, 'foo').enumerable
// false
Object.getOwnPropertyDescriptor(class {foo() {}}.prototype, 'foo').enumerable
// false

super 关键字

  • 关键字用于访问对象字面量或类的原型[[Prototype]]上的属性,或调用父类的构造函数。
  • this关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象
javascript
const proto = {
  foo: 'hello'
};
const obj = {
  foo: 'world',
  find() {
    return super.foo;
  }
};
// 将 proto 设置为 obj 的原型对象
Object.setPrototypeOf(obj, proto);
obj.find() // "hello"
const proto = {
  foo: 'hello'
};
const obj = {
  foo: 'world',
  find() {
    return super.foo;
  }
};
// 将 proto 设置为 obj 的原型对象
Object.setPrototypeOf(obj, proto);
obj.find() // "hello"

注意,super关键字表示原型对象时,只能用在对象的方法之中,用在其他地方都会报错。

对象的拓展运算符

  • 合并对象
  • 解构赋值
  • 复制对象 .....

链式判断运算符?.

ES2020 引入了“链判断运算符”,简化三元运算写法。以及避免一些情况下代码报错。

javascript
// a?.b 等同于 a == null ? undefined : a.b
// a?.b 等同于 a == null ? undefined : a.b

Null 判断运算符 ??

ES2020 引入了一个新的 Null 判断运算符??。它的行为类似||,但是只有运算符左侧的值为nullundefined时,才会返回右侧的值。

  • ??有一个运算优先级问题,它与&&||的优先级孰高孰低。如果多个逻辑运算符一起使用,必须用括号表明优先级,否则会报错。
javascript
lhs && middle ?? rhs // 报错

(lhs && middle) ?? rhs; // 不报错
lhs && middle ?? rhs // 报错

(lhs && middle) ?? rhs; // 不报错

对象新增静态方法

  • Object.is()
  • Object.assign()
  • Object.getOwnPropertyDescriptors()
  • Object.setPrototypeOf()
  • Object.getPrototypeOf()
  • Object.keys()
  • Object.values()
  • Object.entries()
  • Object.fromEntries()