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

tur*_*kus 3 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
Run Code Online (Sandbox Code Playgroud)

为什么都firstObject和secondObject回报3?原型链如何在这里工作?

T.J*_*der 5

因为第一个参数Object.assign是分配对象到.然后Object.assign返回对该对象的引用.它从后续参数中分配,但您不提供任何参数.所以,最终的结果是,firstObject和secondObject刚刚指向同一个对象:

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

var secondObject = Object.assign(firstObject);
console.log("Same object? " + (firstObject === secondObject));
Run Code Online (Sandbox Code Playgroud)

你自找的:

var secondObject = Object.assign({}, firstObject);
// Note -------------------------^^^^
Run Code Online (Sandbox Code Playgroud)

另外请注意,Object.assign复制价值的a来自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")
);
Run Code Online (Sandbox Code Playgroud)


还要注意,正如Epic先生所指出的那样,这里根本没有真正使用原型链.firstObject有自己的财产a,复制后,也是如此secondObject.secondObject不继承firstObject或类似的东西; Object.assign 复制属性.