设置Object.prototype .__ proto__而不仅仅是Object.prototype?

时间:2015-07-17 11:32:54

标签: javascript prototype prototypal-inheritance

我正在查看有关node.js事件模块的这篇文章:

http://www.sitepoint.com/nodejs-events-and-eventemitter/

其中有这段代码:

Door.prototype.__proto__ = events.EventEmitter.prototype;

据说将Door对象的原型设置为event.EventEmitter的原型。

我相信我知道difference between prototype and proto是什么 但是这段代码让我很困惑。所以我的问题是代替使用:

Door.prototype.__proto__ = events.EventEmitter.prototype;

该文章的作者不只是使用这行代码:

Door.prototype= events.EventEmitter.prototype;

2 个答案:

答案 0 :(得分:3)

此代码

Door.prototype.__proto__ = events.EventEmitter.prototype

使Door.prototype继承自events.EventEmitter.prototype

原型链就像

doorInstance -> Door.prototype -> events.EventEmitter.prototype

这种方法类似于

Door.prototype = Object.create(events.EventEmitter.prototype)

不同之处在于修改[[Prototype]]不会创建新对象,但会对性能产生很大的负面影响。

相反,这段代码

Door.prototype = events.EventEmitter.prototype

使Door个实例直接从events.EventEmitter.prototype继承。

也就是说,您无法在Door.prototype中添加特定方法而不会污染events.EventEmitter.prototype

答案 1 :(得分:1)

我对此做了一些更多的研究,虽然有关于这个问题的各种图表,我认为这个图形最好地解释了:

http://www.mollypages.org/misc/js.mp

总结:

  1. Door.prototype只适用于Door类型,不适用于Door的实例。

  2. 在创建doorInstance时,doorInstance .__ proto_设置为Door.prototype(指向Door.prototype)查看新门()。

  3. 有趣的是,Door.prototype有一个自己的__proto_属性(Door.prototype .__ proto_),它指向Object.prototype。

  4. 当属性作为Javascript原型继承的一部分被查找时,__ proto属性将用于原型链中的每个对象。我们可以忘记prototype属性,因为它不存在于实例中。例如doorInstace - > doorInstance .__ proto_ - > doorInstance .__原_.__ proto_。所以最后要查找的最后一个__proto_将是指向Object.prototype的那个。

  5. 回到这个问题,设置Door.prototype .__ proto_就像这样:

    Door.prototype.__proto_ = events.EventEmitter.prototype
    

    实际上会将Door.prototype .__ proto_更改为指向events.EventEmitter.prototype而不是Object.prototype。这样,将按以下顺序查找doorInstance上的属性: doorInstance - > doorInstance .__ proto_ - > doorIntacne .__ proto _.__ proto(events.EventEmitter.prototype)

    这样,doorInstance基本上是从events.EventEmitter.prototype继承的。

    此代码:

    Door.prototype = events.EventEmitter.prototype;
    

    具有相同的效果,因为doorInstance .__ proto_指向Door.prototype并将Door.prototype设置为events.EventEmitter.prototype将使doorInstance .__ proto_指向events.EventEmitter.prototype。这样,将按以下顺序查找doorInstance上的属性: doorInstance - > doorInstance .__ proto_(events.EventEmitter.prototype)。

    然而正如Oriol已经回答的那样,因为Door.prototype和events.EventEmitter.prototype现在指向同一个对象,原型中的更改将影响另一个原型,这可能会导致意外行为。