属性描述对象
// 默认值
{
value: undefined,
writable: true,
enumerable: true,
configurable: true,
get: undefined,
set: undefined
}
// 属性描述对象提供6个元属性。
对象的拷贝
var extend = function (to, from) {
for (var property in from) {
to[property] = from[property];
}
return to;
}
extend({}, {
a: 1
})
// {a: 1}
// 为了解决这个问题,我们可以通过Object.defineProperty方法来拷贝属性。
var extend = function (to, from) {
for (var property in from) {
if (!from.hasOwnProperty(property)) continue;
Object.defineProperty(
to,
property,
Object.getOwnPropertyDescriptor(from, property)
);
}
return to;
}
extend({}, { get a(){ return 1 } })
// { get a(){ return 1 } })
// 上面代码中,hasOwnProperty那一行用来过滤掉继承的属性,否则可能会报错,因为Object.getOwnPropertyDescriptor读不到继承属性的属性描述对象。
function copyObject(orig) {
var copy = Object.create(Object.getPrototypeOf(orig));
copyOwnPropertiesFrom(copy, orig);
return copy;
}
function copyOwnPropertiesFrom(target, source) {
Object
.getOwnPropertyNames(source)
.forEach(function (propKey) {
var desc = Object.getOwnPropertyDescriptor(source, propKey);
Object.defineProperty(target, propKey, desc);
});
return target;
}
// 另一种更简单的写法,是利用 ES2017 才引入标准的Object.getOwnPropertyDescriptors方法。
function copyObject(orig) {
return Object.create(
Object.getPrototypeOf(orig),
Object.getOwnPropertyDescriptors(orig)
);
}