在Node.js的Express模块的代码中,我遇到了这一行,为服务器设置了继承:
Server.prototype.__proto__ = connect.HTTPServer.prototype;
我不确定这是做什么的 - MDC文档(https://developer.mozilla.org/en/JavaScript/Guide/Inheritance_Revisited#prototype_and_原)似乎说我可以做:
Server.prototype = connect.HTTPServer.prototype;
的确,我做了这个测试:
var parent = function(){}
parent.prototype = {
test: function(){console.log('test')};
}
var child1 = function(){};
child1.prototype = parent.prototype;
var instance1 = new child1();
instance1.test(); // 'test'
var child2 = function(){};
child2.prototype.__proto__ = parent.prototype;
var instance2 = new child2();
instance2.test(); // 'test'
看起来一样吗?所以,是的,我想知道设置object.prototype .__ proto是为了什么。谢谢!
看看图表 这一页 (mckoss.com)显示了 prototype
, constructor
, __proto__
小层次的关系。此外,图下方的代码也很好地描述了这种关系。
当你有一个功能 Base
,并设置定义的函数对象的原型,语句 Derived.prototype = new Base;
设置 __proto__
(实际上是内部的 [[prototype]]
)的 Derived.prototype
至 Base.prototype
自动,使Derived本身成为一个可以实例化对象的类。这似乎是一种更符合标准的定义派生类的方法。
从我读到的, __proto__
是一种访问内部的非标准方式 [[prototype]]
一个对象。它似乎得到了很好的支持,但我不确定它是否应该被信任。
无论如何,你的例子 Server.prototype.__proto__ = connect.HTTPServer.prototype;
似乎以相反的方式进行推导:首先定义一个对象, Server
通过定义构造函数和proto,然后挂钩内部 [[prototype]]
手动将其变形为派生自的类 HTTPServer
。
至于你建议的替代方案, Server.prototype = connect.HTTPServer.prototype;
:这是一个坏主意。在这里,您正在设置原型 Server
与原型相同的对象 HTTPServer
。所以你做的任何改变 Server
上课将直接反映在 HTTPServer
,并且可以从其他派生类访问 HTTPServer
。如果两个类派生出来,你可以想象混沌 HTTPServer
尝试定义相同的成员。
非标准的财产 __proto__
让你设置一个原型 现有 目的。
在您的示例中,两个版本都将达到相同的效果,但存在差异:
child1
的原型与之相同 parent
的原型,而 child2
原型是一个空对象,这个空对象的原型与之相同 parent
的原型。
当然是 child2
它的原型没有方法 test
,这个方法将在原型链中进一步查找。
还要考虑这个:
您只想创建一个应该从另一个对象继承的对象。现在,您可以编写构造函数,但JavaScript具有对象文字表示法来直接创建对象,并且您希望使用它。
如果你有一个构造函数,让新对象继承另一个对象就像设置一样容易 prototype
该对象的构造函数。
显然这对于对象文字不起作用。但在Firefox中你可以使用 __proto__
设置它:
var server = {
__proto__: connect.HTTPServer.prototype,
other: properties
};
由于此属性不是标准属性,因此应避免使用它。