1.属性的简洁表示法
function f(x, y) {
return {x, y};
}
// 等同于
function f(x, y) {
return {x: x, y: y};
}
f(1, 2) // Object {x: 1, y: 2}
广泛的应用于写对象时对象的属性书写简化
var birth = '2000/01/01';
var Person = {
name: '张三',
//等同于birth: birth
birth,
// 等同于hello: function ()...
hello() { console.log('我的名字是', this.name); }
};
<h3><b>1.属性的简洁表示法</b></h3>
var lastWord = 'last word';
var a = {
'first word': 'hello',
[lastWord]: 'world'
};
a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"
需要注意的点是:
1.属性名表达式与简洁表示法,不能同时使用,会报错
// 报错
var foo = 'bar';
var bar = 'abc';
var baz = { [foo] };
// 正确
var foo = 'bar';
var baz = { [foo]: 'abc'};
2.属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[object Object]。
const keyA = {a: 1};
const keyB = {b: 2};
const myObject = {
[keyA]: 'valueA',
[keyB]: 'valueB'
};
myObject // Object {[object Object]: "valueB"}
2.Object.is()用于判断两个值是否严格等于
es5的判断是否等于的运算符有相等运算符(==)(只能判断值是否等于)和严格相等运算符(===)(值和类型都会判断),缺点是前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0。
es6提出Object.is用来比较两个值是否严格相等。
Object.is('foo', 'foo')
// true
Object.is({}, {})
// false都是对象,但是对象内部的东西是否相等,就无从判断。
Object.is和(===)比较
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
3.Object.assign()用于合并对象
var target = { a: 1 };
var source1 = { b: 2 };
var source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
特殊的用法
- 如果只有一个参数,Object.assign会直接返回该参数。
- 如果该参数不是对象,则会先转成对象,然后返回。
- 只有一个参数的情况下由于undefined和null无法转成对象,所以如果它们作为参数,就会报错。
- 若undefined和null不在首参数,就不会报错。
var obj = {a: 1};
Object.assign(obj) === obj // true
typeof Object.assign(2) // "object"
Object.assign(undefined) // 报错
Object.assign(null) // 报错
let obj = {a: 1};
Object.assign(obj, undefined) === obj // true
Object.assign(obj, null) === obj // true
常见的用途
(1)为对象添加属性
class Point {
constructor(x, y) {
Object.assign(this, {x, y});
}
}
(2)为对象添加方法
Object.assign(SomeClass.prototype, {
someMethod(arg1, arg2) {
···
},
anotherMethod() {
···
}
});
// 等同于下面的写法
SomeClass.prototype.someMethod = function (arg1, arg2) {
···
};
SomeClass.prototype.anotherMethod = function () {
···
};
(3)克隆对象
function clone(origin) {
return Object.assign({}, origin);
}
(4)合并多个对象
const merge =
(target, ...sources) => Object.assign(target, ...sources);
(5)为属性指定默认值
const DEFAULTS = {
logLevel: 0,
outputFormat: 'html'
};
function processContent(options) {
options = Object.assign({}, DEFAULTS, options);
console.log(options);
// ...
}
4.属性的遍历
ES6 一共有5种方法可以遍历对象的属性。
- for...in
for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。
- Object.keys(obj)
Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)。
- Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)。
- Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性。
- Reflect.ownKeys(obj)
Reflect.ownKeys返回一个数组,包含对象自身的所有属性,不管属性名是 Symbol 或字符串,也不管是否可枚举。
以上的5种方法遍历对象的属性,都遵守同样的属性遍历的次序规则。
- 首先遍历所有属性名为数值的属性,按照数字排序。
- 其次遍历所有属性名为字符串的属性,按照生成时间排序。
- 最后遍历所有属性名为 Symbol 值的属性,按照生成时间排序。
5.Null 传导运算符
编程实务中,如果读取对象内部的某个属性,往往需要判断一下该对象是否存在。比如,要读取message.body.user.firstName,安全的写法是写成下面这样。
const firstName = (message && message.body && message.body.user && message.body.user.firstName) || 'default';
这样的层层判断非常麻烦,因此引入了“Null 传导运算符”(null propagation operator)?.,简化上面的写法。
const firstName = message?.body?.user?.firstName || 'default';
上面代码有三个?.运算符,只要其中一个返回null或undefined,就不再往下运算,而是返回undefined。
“Null 传导运算符”有四种用法。
obj?.prop
// 读取对象属性
obj?.[expr]
// 同上
func?.(...args)
// 函数或对象方法的调用
new C?.(...args)
// 构造函数的调用