使用Object.assign和描述符的原型链

时间:2016-10-02 15:28:09

标签: javascript

让我们考虑一下这种情况:



var firstObject = {
  set a(val) {
  	this._a_ = val;
  },
  get a() {
  	return this._a_;
  }
}

var secondObject = Object.assign(firstObject);

secondObject.a = 3;

console.log(secondObject.a); // 3
console.log(firstObject.a); // 3

console.log(secondObject.hasOwnProperty('a')); // true
console.log(firstObject.hasOwnProperty('a')); // true




为什么firstObjectsecondObject都返回3? 原型链如何在这里工作?

1 个答案:

答案 0 :(得分:5)

因为Object.assign的第一个参数是将指定给的对象。然后Object.assign返回对该对象的引用。它从后续参数中指定,但您没有提供任何参数。因此,最终结果是firstObjectsecondObject只指向同一个对象:

var firstObject = {
  set a(val) {
  	this._a_ = val;
  },
  get a() {
  	return this._a_;
  }
}

var secondObject = Object.assign(firstObject);
console.log("Same object? " + (firstObject === secondObject));

你想:

var secondObject = Object.assign({}, firstObject);
// Note -------------------------^^^^

另请注意,Object.assigna的{​​em>值从firstObject复制到该新对象,而不是其属性描述符。因此a上的secondObject属性只是一个简单的属性,而不是访问者。

这是一个带有上述更改的片段,并在最后显示每个对象的描述符:

var firstObject = {
  set a(val) {
  	this._a_ = val;
  },
  get a() {
  	return this._a_;
  }
}

var secondObject = Object.assign({}, firstObject);

secondObject.a = 3;

console.log(secondObject.a); // 3
console.log(firstObject.a);  // undefined

firstObject.a = 42;
console.log(firstObject.a);  // 42
console.log(secondObject.a); // still 3

console.log(
  "firstObject's a descriptor:",
  Object.getOwnPropertyDescriptor(firstObject, "a")
);
console.log(
  "secondObject's a descriptor:",
  Object.getOwnPropertyDescriptor(secondObject, "a")
);

另请注意,作为Mister Epic pointed out,根本没有真正使用原型链。 firstObject有一个拥有属性a,在复制之后,secondObject也是如此。 secondObject不会继承firstObject或类似内容; Object.assign 复制属性。