什么是JavaScript的Object.prototype行为? [英] What's the JavaScript's Object.prototype behavior?
问题描述
我遇到了一段奇怪的代码片段,我根本无法理解,这里是:
I ran into a strange snippet of code, which I cannot understand at all, here it is:
var obj = function() {};
obj.prototype.x = 5;
var instance1 = new obj();
obj.prototype = {y: 6};
var instance2 = new obj();
console.log(instance1.x, instance1.y, instance2.x, instance2.y);
// 5, undefined, undefined, 6
现在,问题是:
- 为什么此记录
5,未定义,未定义,6
而不是undefined,6,undefined,6
? - 为什么替换原型并没有改变原型的所有实例的原型对象,就像通常那样?
- V8引擎在这段代码中一步一步地做什么?
- 编辑:我将如何更改所有实例的原型?
- Why is this logging
5, undefined, undefined, 6
instead ofundefined, 6, undefined, 6
? - Why replacing the prototype is not changing the prototype of all the instances of the object, as it would usually do?
- What is the V8 engine doing, step by step, in this code?
- How would I go about changing the prototype of ALL the instances?
感谢每一个解释。
推荐答案
根据 ECMA脚本5规范,
原型
属性的值用于初始化新创建的对象的[[Prototype]]
内部属性,然后调用Function对象这个新创建的对象的构造函数。
The value of the
prototype
property is used to initialise the[[Prototype]]
internal property of a newly created object before the Function object is invoked as a constructor for that newly created object.
很明显 prototype
是只是为了初始化 [[Prototype]]
属性。当我们创建一个对象时, [[Prototype]]
被设置为构造函数的 prototype
对象,原型链是成立。在你的情况下,你做的时候
It is clear that prototype
is just to initialize the [[Prototype]]
property. When we create an object, [[Prototype]]
is set as the constructor function's prototype
object and the prototype chain is established. In your case, when you do
var obj = function() {};
obj.prototype.x = 5;
var instance1 = new obj();
[[Prototype]]
看起来像这个
console.log(Object.getPrototypeOf(instance1));
# { x: 5 }
(是的,你可以访问 [[Prototype]]
with Object.getPrototypeOf
function)
(Yes, you can access the [[Prototype]]
with Object.getPrototypeOf
function)
因此,当JS引擎在 instance1
中查找 x
时,它会将值视为 5
且由于 y
未定义,因此它使用 undefined
。
So, when JS Engine looks for x
in instance1
, it finds the value as 5
and since y
is not defined, it uses undefined
.
在第二种情况下,
obj.prototype = {y: 6};
var instance2 = new obj();
您正在更改原型
对象 obj
,这样使用此函数构造的新对象将使用分配给它的新对象。所以, [[Prototype]]
看起来像这样,对于 instance2
you are changing the prototype
object of obj
, so that the new objects constructed with this functions will use the new object assigned to it. So, [[Prototype]]
looks like this, for instance2
console.log(Object.getPrototypeOf(instance2));
# { y: 6 }
这就是为什么, instance2
中找不到 x
,但是 y
。
That is why, instance2
couldn't find x
in it, but y
.
要回答更新的问题,
编辑:我将如何更改所有实例的原型?
How would I go about changing the prototype of ALL the instances?
您可以使用<$ c更改旧对象的原型$ c> Object.setPrototypeOf ,像这样
Object.setPrototypeOf(instance1, {
y: 6
});
因为,这使得 [[Prototype]]
instance1
与 instance2
不同,我们只需更新构造函数的原型
object,像这样
Since, this makes the [[Prototype]]
of instance1
different from instance2
, we can just update the constructor function's prototype
object, like this
delete obj.prototype.x;
obj.prototype.y = 6;
现在,我们没有改变 instance1的内部属性
和 instance2
。我们可以像这样检查
Now, we havn't changed the internal property of both instance1
and instance2
. We can check that like this
console.log(Object.getPrototypeOf(instance1) === Object.getPrototypeOf(instance2));
# true
console.log(Object.getPrototypeOf(instance1) === obj.prototype);
# true
注意:约定是命名构造函数,首字母为大写字母。
Note: The convention is to name the constructor functions with the initial letter a capital letter.
这篇关于什么是JavaScript的Object.prototype行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!