属性的简洁表示法
可直接写入变量和函数作为对象的属性和方法
let foo = '123';
let baz = { foo }; // baz——{foo: 123}
// 等同于
baz = { foo: foo };
let o = {
method() {
.....
}
}
// 等同于
let o = {
method: function () {
.....
}
}
如果某个方法的值是一个 Generator 函数,则需要在其前面加上星号
let obj = {
* m() {
yield 'hello world';
}
}
属性名表达式
定义对象的属性有两种方法:
let obj = {};
obj.foo = true;
obj['a' + 'bc'] = 123;
表达式还可以用于定义方法名:
let obj = {
['h' + 'ello']() {
return 'hi!';
}
}
Object.is()
用来不叫你两个值是否严格相等,与( === )的行为基本一致,除了以下两点:
- +0 不等于 -0
- NaN等于自身
Object.is(+0, -0); // false
Object.assign()
用来将源对象的所有可枚举属性(不复制继承属性)复制到目标对象中,采用的是浅复制。如果源对象某个属性的值是对象,目标对象复制得到的是这个对象的引用。
let obj1 = {a:1};
let obj2 = Object.assign({},obj1);
obj1.a = 2;
obj2.a // 1
let obj3 = { a: { b: 1} };
let obj4 = Object.assign({}, obj3);
obj3.a.b = 2;
obj4.a.b // 2
第一个参数为目标对象,后边的参数是源对象:
-
只有一个参数:如果该参数为对象,直接返回该参数;如果不是对象,转成对象后返回,undefined 和 null 无法转为对象,报错
let obj = { a: 1}; Object.assign({ a: 1 }) === obj; // true -
多个参数:源对象参数不是对象,转为对象(无法转为对象则跳过,不报错)。数值、字符串、布尔值只有字符串会以数组的形式复制到目标对象,其他值没有效果
let v1 = 'abc'; let v2 = true; let v3 = 10; Object.assign({}, v1, v2, v3); // {'0': 'a', '1': 'b', 2: 'c'}
属性的可枚举性
Object.getOwnPropertyDescriptor() 方法可以获取属性的描述对象,其中的 enumerable 属性为可枚举性。所有 Class 的原型的方法都是不可枚举的。
let obj = { foo: "123" };
Object.getOwnPropertyDescriptor(obj, 'foo');
// { configurable: true, enumerable: true, value: "123", writable: true }
Object.getOwnPropertyDescriptor(class { foo() {} }.prototype, 'foo').enumerable; // false
属性的遍历
- for ... in:对象自身和继承的可枚举属性(不包括 Symbol 属性)
- Object.keys(obj):对象自身的可枚举属性(不包括 Symbol 属性)
- Object.getOwnPropertyNames(obj):对象自身的所有属性(包括不可枚举属性,但不包括 Symbol 属性)
- Object.getOwnPropertySymbols(obj):对象自身的所有 Symbol 属性
- Reflect.ownKeys(obj):对象自身的所有属性(包括 Symbol 属性和不可枚举属性)
以上方法遍历属性时遵循下列顺序:
- 首先遍历属性名为数值的属性,按照数字由小到大排序;
- 其次遍历属性名为字符串的属性,按照对象中位置从前到后排序;
- 最后遍历属性名为 Symbol 值的属性,按照对象中位置从前到后排序
__proto__属性、Object.setPrototypeOf()、Object.getPrototypeOf()
__proto__属性用来读取或设置当前对象的 prototype 对象。(尽量用以下两种代替)
Object.setPrototypeOf() 用来设置一个对象的 prototype 对象。参数不是对象时自动转换为对象。
Object.getPrototypeOf() 用来读取一个对象的 prototype 对象。参数不是对象时自动转换为对象。
Object.getPrototypeOf(1) === Number.prototype ; // true
Object.getPrototypeOf('foo') === String.Prototype; // true
Object.getPrototypeOf(true) === Boolean.Prototype; // true
Object.getOwnPropertyDescriptors()
Object.getOwnPropertyDescriptors() 返回指定对象的所有属性(不包括继承属性)的描述对象
Null 传导运算符
假如想获取对象 obj 内部的 name 属性,安全的写法是:
let name = (obj && obj.person && obj.person.user && obj.person.user.name) || 'default' ;
Null 传导运算符可以简化上述操作:
let name = obj?.person?.user?.name || 'default' ;
“ ?. ” 表示只要其中有一个返回 null 或者 undefined ,就不再继续运算,返回 undefined。
其中,有以下4种用法:
- obj?.prop:读取对象属性
- obj?.[prop]:读取对象属性
- func?.(...args):函数或对象方法的调用
- new Person?.(...args):构造函数的调用