首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaScript的Object.prototype行为是什么?

JavaScript的Object.prototype行为是什么?
EN

Stack Overflow用户
提问于 2014-10-12 10:55:42
回答 5查看 1.2K关注 0票数 12

我遇到了一个奇怪的代码片段,我完全无法理解,如下所示:

代码语言:javascript
复制
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, undefined, undefined, 6而不是undefined, 6, undefined, 6
  2. 为什么替换原型并不像通常那样改变对象的所有实例的原型?
  3. 在这段代码中,V8引擎一步一步地在做什么?
  4. 编辑:我将如何改变所有实例的原型?

每一种解释都很感激。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-10-12 11:13:49

ECMA脚本5规范称,

在函数对象作为新创建对象的构造函数被调用之前,prototype属性的值用于初始化新创建对象的[[Prototype]]内部属性。

很明显,prototype只是初始化[[Prototype]]属性。在创建对象时,将[[Prototype]]设置为构造函数的prototype对象,并建立原型链。在你的情况下,当你这样做

代码语言:javascript
复制
var obj = function() {};
obj.prototype.x = 5;

var instance1 = new obj();

[[Prototype]]看起来像这样

代码语言:javascript
复制
console.log(Object.getPrototypeOf(instance1));
# { x: 5 }

(是的,您可以使用[[Prototype]]函数访问Object.getPrototypeOf )

因此,当JS引擎在instance1中查找instance1时,它会找到5的值,并且由于y没有定义,所以它使用undefined

在第二个案例中,

代码语言:javascript
复制
obj.prototype = {y: 6};

var instance2 = new obj();

您正在更改prototype对象的obj,以便使用此函数构造的新对象将使用分配给它的新对象。所以,[[Prototype]]看起来像这样,对于instance2来说

代码语言:javascript
复制
console.log(Object.getPrototypeOf(instance2));
# { y: 6 }

这就是为什么,instance2在里面找不到x,但是y

为了回答最新的问题,

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

您可以用Object.setPrototypeOf更改旧对象的原型,如下所示

代码语言:javascript
复制
Object.setPrototypeOf(instance1, {
    y: 6
});

因为,这使得[[Prototype]] of instance1不同于instance2,所以我们只需更新构造函数的prototype对象,如下所示

代码语言:javascript
复制
delete obj.prototype.x;
obj.prototype.y = 6;

现在,我们没有改变instance1instance2的内部属性。我们可以这样检查

代码语言:javascript
复制
console.log(Object.getPrototypeOf(instance1) === Object.getPrototypeOf(instance2));
# true
console.log(Object.getPrototypeOf(instance1) === obj.prototype);
# true

注释:惯例是用大写字母命名构造函数。

票数 7
EN

Stack Overflow用户

发布于 2014-10-12 11:00:27

解释

因此,首先,您的两行代码创建一个函数obj,并将其分配给它的原型{x: 5}

当您创建此对象的实例时,它似乎有一个对原型的内部引用,该原型是new'd时存在的。

在此之后,您将原型重新分配到{y: 6},这不影响对第一个原型的instance1内部引用。

然后,当您创建instance2时,它有一个对第二个原型的内部引用,因此,记录它们将生成5, undefined, undefined, 6

#4

您可以,而不是将原型重新分配到一个新对象:

代码语言:javascript
复制
obj.prototype = {y: 6};

改为修改原型:

代码语言:javascript
复制
delete obj.prototype.x; // Setting to undefined should produce same behaviour
obj.prototype.y = 6;

这将产生输出:undefined, 6, undefined, 6

我已经用Chrome上的http://jsfiddle.net/9j3260gp/和Windows上的火狐最新版本对此进行了测试。

票数 9
EN

Stack Overflow用户

发布于 2014-10-12 11:00:25

prototype是一种与后台新特性相结合的特性。它适用于与new一起使用的该函数的所有实例。在第一个示例中,将.x =5附加到原型中,所创建的实例的值为.x =5。稍后,您将原型修改为一个新对象。这就是在任何新实例中使用的原型。这就是为什么第一个实例只有.x = 5,第二个实例只有.y =6。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26324395

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档