对象拓展
属性的简洁表示
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 判断运算符??
。它的行为类似||
,但是只有运算符左侧的值为null
或undefined
时,才会返回右侧的值。
??
有一个运算优先级问题,它与&&
和||
的优先级孰高孰低。如果多个逻辑运算符一起使用,必须用括号表明优先级,否则会报错。
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()