ES6总结系列之 对象的扩展 篇
1. 属性、方法简洁表示法
属性简写
const foo = 'bar';
const baz = {foo}; //属性名就是变量名, 属性值就是变量值
baz // {foo: "bar"}
// 等同于
const baz = {foo: foo};
方法简写
const obj = {
method () {
return 'Hello!'
}
}
//等同于
const obj = {
method: function () {
return 'Hello!'
}
}
简写的对象方法不能用作构造函数,会报错。
const obj = {
f() {
this.foo = 'bar';
}
};
new obj.f() // 报错
2. 属性名表达式
JavaScript 定义对象的属性,有两种方法。
// 方法一
obj.foo = true;
//直接用标识符作为属性名
// 方法二
obj['a' + 'bc'] = 123;
//用表达式作为属性名,须将表达式放在方括号之内
①使用字面量方式定义对象(使用大括号),在 ES5 中只能使用方法一(标识符)定义属性。ES6 允许字面量定义对象时,用方法二(表达式)作为对象的属性名,即把表达式放在方括号内。
let lastWord = 'last word';
const a = {
'first word': 'hello',
[lastWord]: 'world'
};
a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"
②表达式还可以用于定义方法名
let obj = {
['h' + 'ello']() {
return 'hi';
}
};
obj.hello() // hi
③属性名表达式与简洁表示法,不能同时使用
// 报错
const foo = 'bar';
const bar = 'abc';
const baz = { [foo] };
// 正确
const foo = 'bar';
const baz = { [foo]: 'abc'};
④属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[object Object],这一点要特别小心。
const keyA = {a: 1};
const keyB = {b: 2};
const myObject = {
[keyA]: 'valueA',
[keyB]: 'valueB'
};
myObject // Object {[object Object]: "valueB"}
3.属性的可枚举和遍历
可枚举性
①每个对象都有一个描述对象(Descriptor),来控制属性的行为
②用Object.getOwnPropertyDescriptor ()来获取
let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
// {
// value: 123,
// writable: true,
// enumerable: true,
// configurable: true
// }
③enumerable为false时,为不可枚举,四种操作会忽略enumerable为false的属性
1)for...in
循环 返回自身和继承的可枚举属性
2)Object.keys(obj)
返回可枚举的key数组
3)JSON.stringify()
串化可枚举的属性
4)Object.assign()
拷贝自身可枚举的属性
5)其中只有 for...in
会遍历继承的属性,其他只遍历自身属性
属性的遍历
④五种属性的遍历
1)for…in
2)Object.keys(obj) 返回数组
3)Object.getOwnPropertyNames(obj) 返回数组
4)Object.getOwnPropertySymbols(obj) 返回数组
5)Reflect.ownKeys(obj) 返回数组
6)(1)(2)(3)不含Symbol属性,(4)(5)含Symbol属性,(3)(5)包含不可枚举属性
⑤遍历顺序
数值键 --> 字符串键 --> Symbol键
(数值升序) - (时间升序) - (时间升序)
4.super关键字
1)指向对象原型
2)只能用在对象的方法中
3)只能用在对象简写法可以让JavaScript引擎确认,定义的是对象的方法
const proto = {
foo: 'hello'
};
const obj = {
foo: 'world',
find() {
return super.foo;
}
};
Object.setPrototypeOf(obj, proto);
obj.find() // "hello"
5.对象的扩展运算符
1)解构赋值要求求等号右边是一个对象,所以如果等号右边是undefined或null,就会报错,因为它们无法转为对象
2)扩展运算符的解构赋值不能复制继承制原型对象上的属性
3)let { x, …{ y, z } } = o; 错误
4)解构赋值的拷贝是浅拷贝
5)如果有取值函数get,这个函数是会执行的
6.链判断运算符 ES2020引入?.
1)const firstName = message?.body?.user?.firstName || ‘default’;
2)等号右边的对象如果是null或undefined,就返回undefined,不在往下计算
3)三种用法:
a.obj?.prop //对象属性
b.obj?.[prop] //对象属性
c.func?.(…args)//函数或对象方法的调用
4)右侧不能是十进制数,不然?.不在被看成一个完整的运算符,小数点.会和后面的数字结合成小数,将变成一个三目运算符
7.Null判断运算符(??)
1)ES2020 引入了一个新的 Null 判断运算符??。它的行为类似||,但是只有运算符左侧的值为null或undefined时,才会返回右侧的值。 (0和false不生效)
const headerText = response.settings.headerText ?? 'Hello, world!';
- 个人Github,欢迎star^_^
- ES6总结系列参考自阮一峰《ECMAScript6入门》