什么是JavaScript的Object.prototype行为? [英] What's the JavaScript's Object.prototype behavior?

查看:164
本文介绍了什么是JavaScript的Object.prototype行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一段奇怪的代码片段,我根本无法理解,这里是:

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

现在,问题是:


  1. 为什么此记录 5,未定义,未定义,6 而不是 undefined,6,undefined,6

  2. 为什么替换原型并没有改变原型的所有实例的原型对象,就像通常那样?

  3. V8引擎在这段代码中一步一步地做什么?

  4. 编辑:我将如何更改所有实例的原型?

  1. Why is this logging 5, undefined, undefined, 6 instead of undefined, 6, undefined, 6?
  2. Why replacing the prototype is not changing the prototype of all the instances of the object, as it would usually do?
  3. What is the V8 engine doing, step by step, in this code?
  4. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆