Javascript 将新对象分配给函数原型,删除实例和函数原型之间的 link
Javascript assigning a new object to a function prototype, removes the link between the instance and the function prototype
function User() {
this.name = "name";
}
User.prototype.age = 10;
const user1 = new User(); // user1 -> { name: "name" }
console.log(user1.age) // prints 10
console.log(user1.__proto__ === user.prototype) // prints true
// if i change the age value on prototype, then user1.age will return the new value
User.prototype.age = 20;
console.log(user1.age) // prints 20
上面的代码按预期工作,因为当我用关键字 new
调用“用户”函数时,它将 return 一个只有 name
属性 和该对象将 linked 为 User.prototype
。
但是我没有得到的是当我为原型分配一个对象时,不再有 link。
User.prototype = {age: 30};
console.log(user1.age) // prints 20! , Why?, shouldn't it print 30?
console.log(user1.__proto__ === User.prototype) // prints false
P.S:即使link丢失了,因为User.porotype的引用已经改变了,但是为什么user1.age
仍然是return20
不是 undefined
编辑:正如答案所提到的,这与 prototype
无关,我很困惑,因为我认为对象引用就像一个指针,但实际上不是。这里已经回答了 Javascript pointer/reference craziness. Can someone explain this?
当您重新分配 .prototype
属性 时,曾经将其内部原型指向旧原型的旧实例 不会更改 。请参阅 setPrototypeOf
:
上的文档
Warning: Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, currently a very slow operation in every browser and JavaScript engine. In addition, the effects of altering inheritance are subtle and far-flung, and are not limited to simply the time spent in the Object.setPrototypeOf(...) statement, but may extend to any code that has access to any object whose [[Prototype]] has been altered.
如果旧实例的原型自动更新,这将是一项非常昂贵的操作,并且可能导致奇怪的损坏。将新对象分配给 .prototype
只会影响 new 个实例。
如果您想更新现有实例的原型,则必须手动进行(仅供参考 - 一开始就想这样做是一件非常奇怪的事情)
function User() {
}
const user1 = new User();
User.prototype = { age: 30 };
Object.setPrototypeOf(user1, User.prototype);
console.log(user1.age)
console.log(user1.__proto__ === User.prototype)
当你声明const user1 = new User();
时,在幕后你会得到user1.__proto__ = User.prototype
。
稍后将User.prototype
重新分配给另一个对象不会影响user1.__proto__
,值将保持与之前相同,它会保留对原始原型对象的引用。
事实上,它与 prototype
无关,它只是与以下示例中的对象矫揉造作有关:
let obj1 = {a: 2};
const obj2 = obj1;
obj1 = {b: 2}
console.log(obj2); // print {a: 2}
function User() {
this.name = "name";
}
User.prototype.age = 10;
const user1 = new User(); // user1 -> { name: "name" }
console.log(user1.age) // prints 10
console.log(user1.__proto__ === user.prototype) // prints true
// if i change the age value on prototype, then user1.age will return the new value
User.prototype.age = 20;
console.log(user1.age) // prints 20
上面的代码按预期工作,因为当我用关键字 new
调用“用户”函数时,它将 return 一个只有 name
属性 和该对象将 linked 为 User.prototype
。
但是我没有得到的是当我为原型分配一个对象时,不再有 link。
User.prototype = {age: 30};
console.log(user1.age) // prints 20! , Why?, shouldn't it print 30?
console.log(user1.__proto__ === User.prototype) // prints false
P.S:即使link丢失了,因为User.porotype的引用已经改变了,但是为什么user1.age
仍然是return20
不是 undefined
编辑:正如答案所提到的,这与 prototype
无关,我很困惑,因为我认为对象引用就像一个指针,但实际上不是。这里已经回答了 Javascript pointer/reference craziness. Can someone explain this?
当您重新分配 .prototype
属性 时,曾经将其内部原型指向旧原型的旧实例 不会更改 。请参阅 setPrototypeOf
:
Warning: Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, currently a very slow operation in every browser and JavaScript engine. In addition, the effects of altering inheritance are subtle and far-flung, and are not limited to simply the time spent in the Object.setPrototypeOf(...) statement, but may extend to any code that has access to any object whose [[Prototype]] has been altered.
如果旧实例的原型自动更新,这将是一项非常昂贵的操作,并且可能导致奇怪的损坏。将新对象分配给 .prototype
只会影响 new 个实例。
如果您想更新现有实例的原型,则必须手动进行(仅供参考 - 一开始就想这样做是一件非常奇怪的事情)
function User() {
}
const user1 = new User();
User.prototype = { age: 30 };
Object.setPrototypeOf(user1, User.prototype);
console.log(user1.age)
console.log(user1.__proto__ === User.prototype)
当你声明const user1 = new User();
时,在幕后你会得到user1.__proto__ = User.prototype
。
稍后将User.prototype
重新分配给另一个对象不会影响user1.__proto__
,值将保持与之前相同,它会保留对原始原型对象的引用。
事实上,它与 prototype
无关,它只是与以下示例中的对象矫揉造作有关:
let obj1 = {a: 2};
const obj2 = obj1;
obj1 = {b: 2}
console.log(obj2); // print {a: 2}