1 属性的简洁表示法
ES6允许直接写入变量和函数,作为对象的属性和方法。这种写法更加简洁
const foo = 'bar';
const baz = {foo};
bar // {foo: 'bar'}
// 等同于
const baz = {foo: foo}
function f(x, y) {
return {x, y};
}
// 等同于
function f(x, y) {
return {x: x, y: y};
}
f(1, 2) // Object {x: 1, y: 2}
方法也是可以简写:
const o = {
method() {
return "Hello!";
}
};
// 等同于
const o = {
method: function() {
return "Hello!";
}
};
实际中的例子
function getPoint() {
const x = 1;
const y = 10;
return {x, y};
}
getPoint()
// {x:1, y:10}
属性的赋值器(setter)和取值器(getter),事实上也是采用这种写法。
const cart = {
_wheels: 4,
get wheels () {
return this._wheels;
},
set wheels (value) {
if (value < this._wheels) {
throw new Error('数值太小了!');
}
this._wheels = value;
}
}
2 属性名表达式
Javascript定义对象的属性,有两种方法。
// 方法一
obj.foo = true;
// 方法二
obj['a' + 'bc'] = 123;
console.log(obj); // Object {foo: true, abc: 123}
但是如果使用字面量方式定义对象(使用大括号),在ES5中只能使用方法一来定义属性。
var obj = {
foo: true,
abc: 123
}
ES6允许字面量定义对象时,使用方法二作为对象的属性名,即把表达式放在方括号内。
let propKey = 'foo';
let obj = {
[propKey]: true,
['a' + 'bc']: 123
};
console.log(obj); // Object {foo: true, abc: 123}
3 方法的name属性
函数的name属性,返回函数名,对象方法也是函数,因此也有name属性。
const person = {
sayName() {
console.log('hello!');
},
};
person.sayName.name // "sayName"
4 Object.assign()
Object.assign方法用于对象的合并,将源对象的所有可枚举属性,复制到目标对象(target)
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
注意,如果目标对象与源对象有同名属性,或对各源对象有同名属性,后面的属性会覆盖前面的属性。
const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
如果只有一个参数,Object.assign 会直接返回该参数
cons obj = {a: 1};
Object.assign(obj) === obj; // true
注意点
(1)浅拷贝
Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
const obj1 = {a: {b: 1}};
const obj2 = Object.assign({}, obj1);
obj1.a.b = 2;
obj2.a.b // 2
上面代码中,源对象obj1的a属性的值是一个对象,Object.assign拷贝得到的是这个对象的引用。这个对象的任何变化,都会反映到目标对象上面。
(2)同名属性的替换
对于这种嵌套的对象,一旦遇到同名属性,Object.assign的处理方法是替换,而不是添加。
const target = { a: { b: 'c', d: 'e' } }
const source = { a: { b: 'hello' } }
Object.assign(target, source)
// { a: { b: 'hello' } }
上面代码中,target对象的a属性被source对象的a属性整个替换掉了,而不会得到
{ a: { b: 'hello', d: 'e' } }
这样的结果,所以需要注意!
(3) 取值函数的处理
Object.assign只能进行值得复制,如果要复制的值是一个取值函数,那么将求值后再复制。
const source = {
get foo() { return 1 }
};
const target = {};
Object.assign(target, source);
// { foo: 1 }
上面代码中,source对象的foo属性是一个取值函数,Object.assign不会复制这个取值函数,只会等拿到值以后,将这个值复制过去。
常见用途
(1)为对象添加方法
Object.assign(SomeClass.prototype, {
someMethod(arg1, arg2) {
···
},
anotherMethod() {
···
}
});
// 等同于下面的写法
SomeClass.prototype.someMethod = function (arg1, arg2) {
···
};
SomeClass.prototype.anotherMethod = function () {
···
};
上面代码使用了对象属性的简介表示法,直接将两个函数放在大括号中,再使用assign方法添加到SomeClass.prototype之中。
(2)克隆对象
function clone(origin) {
return Object.assign({}, origin);
}
上面代码将原始对象拷贝到一个空对象,就得到了原始对象的克隆。
不过采用这种方法克隆,只能克隆到原始对象自身的值,不能克隆它继承的值。
本博客内容摘抄自
阮一峰老师写的ECMAScript6入门一书