以下代码是做什么的:
WeatherWidget.prototype = new Widget;
Widget构造函数在哪里,我想用新函数扩展Widget的“类” WeatherWidget。
Widget
WeatherWidget
什么是 new 关键词在那里做,如果它被省略了,会发生什么?
new
该new关键字调用Widget构造函数,返回值分配给prototype属性。(如果省略new,Widget除非添加了参数列表,否则将不会调用()。但是,以Widget这种方式调用可能是不可能的。如果它不是严格的模式代码并且实现是,则肯定有可能 破坏全局名称空间。 符合ECMAScript版本5.x,因为this在构造函数中它将引用ECMAScript的全局对象。)
prototype
()
this
这样,您的WeatherWidget实例将全部从 同一个 Widget实例继承。原型链将为:
[new WeatherWidget()] → [new Widget()] → [Widget.prototype] → …
这可能很有用,但是大多数时候您都不希望发生这种情况。除非您希望所有WeatherWidget实例 在它们之间共享 从该实例(仅 通过 该实例)继承的 属性值 ,否则不要在此进行操作。另一个问题是您需要以这种方式调用父构造函数,这可能不允许像您一样在没有参数的情况下调用它,或者无法正确初始化。它与模拟类(例如从Java)继承的继承毫无关系。Widget __Widget.prototype
Widget.prototype
function Dummy () {} Dummy.prototype = Widget.prototype; WeatherWidget.prototype = new Dummy(); WeatherWidget.prototype.constructor = WeatherWidget;
该constructor原型属性应该是固定的为好,这样你的WeatherWidget情况下,w将有w.constructor === WeatherWidget预期,而不是w.constructor === Widget。但是,请注意,此后是可枚举的。
constructor
w
w.constructor === WeatherWidget
w.constructor === Widget
这样一来,WeatherWidget情况将通过继承原型链的属性,但不会在它们之间共享的属性值,因为他们继承Widget.prototype通过Dummy它没有自己的属性:
Dummy
[new WeatherWidget()] → [new Dummy()] → [Widget.prototype] → …
在ECMAScript Ed的实现中。5及更高版本,您可以并且应该使用
WeatherWidget.prototype = Object.create(Widget.prototype, { constructor: {value: WeatherWidget} });
代替。这具有额外的优点,即所得的constructor属性不可写,不可枚举或不可配置。
仅当从中显式调用父构造函数时,才会调用WeatherWidget,例如
function WeatherWidget (…) { Widget.apply(this, arguments); }
另请参见Function.prototype.extend()我的JSX:object.js中如何将其概括化。使用该代码,它将变成
Function.prototype.extend()
WeatherWidget.extend(Widget);
My Function.prototype.extend()带有一个可选的第二个参数,您可以使用它轻松地扩展WeatherWidget实例的原型:
WeatherWidget.extend(Widget, { foo: 42, bar: "baz" });
相当于
WeatherWidget.extend(Widget); WeatherWidget.prototype.foo = 42; WeatherWidget.prototype.bar = "baz";
但是,您仍然需要在子构造函数中显式调用父构造函数。该部分不能合理地自动化。但是我向实例Function.prototype.extend()添加了一个_super属性,Function这使它变得更容易:
_super
Function
function WeatherWidget (…) { WeatherWidget._super.apply(this, arguments); }
其他人也实现了类似的扩展。