我正在查看有关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;
答案 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
总结:
Door.prototype只适用于Door类型,不适用于Door的实例。
在创建doorInstance时,doorInstance .__ proto_设置为Door.prototype(指向Door.prototype)查看新门()。
有趣的是,Door.prototype有一个自己的__proto_属性(Door.prototype .__ proto_),它指向Object.prototype。
当属性作为Javascript原型继承的一部分被查找时,__ proto属性将用于原型链中的每个对象。我们可以忘记prototype属性,因为它不存在于实例中。例如doorInstace - > doorInstance .__ proto_ - > doorInstance .__原_.__ proto_。所以最后要查找的最后一个__proto_将是指向Object.prototype的那个。
回到这个问题,设置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现在指向同一个对象,原型中的更改将影响另一个原型,这可能会导致意外行为。