What does the following code do:
WeatherWidget.prototype = new Widget;
where Widget is a constructor, and I want to extend the Widget ‘class’ with a new function WeatherWidget.
What is the new keyword doing there and what would happen if it is left out?
The
newkeyword callsWidgetas a constructor and the return value is assigned to theprototypeproperty. (If you would omitnew, you would not callWidgetunless you added an argument list,(). However, callingWidgetthat way might not be possible. It would certainly have the potential to spoil the global namespace if it is not strict mode code and the implementation is conforming to ECMAScript Ed. 5.x there, because thenthisin the constructor would refer to ECMAScript’s global object.)But this approach actually comes from a really viral bad example in the old Netscape JavaScript 1.3 Guide (mirrored at Oracle, formerly Sun).
This way, your
WeatherWidgetinstances will all inherit from the sameWidgetinstance. The prototype chain will be:This can be useful, but most of the time you would not want it to happen. You should not do that here unless you want all your
WeatherWidgetinstances to share among them the property values they inherit from thisWidgetinstance, and only through it, fromWidget.prototype. Another problem is that you need to call the parent constructor this way, which may not allow to be called without arguments as you do, or would not initialize properly. It certainly has nothing to do with emulation of class-based inheritance as known, e.g., from Java.The proper way to implement class-based inheritance in these prototype-based languages is (originally devised by Lasse Reichstein Nielsen in
comp.lang.javascriptin 2003, for cloning objects):The
constructorprototype property should be fixed as well, so that yourWeatherWidgetinstanceswwould havew.constructor === WeatherWidgetas expected, and notw.constructor === Widget. However, be aware that it is enumerable afterwards.This way,
WeatherWidgetinstances will inherit properties through the prototype chain, but will not share property values among them, because they inherit fromWidget.prototypethroughDummywhich has no own properties:In implementations of ECMAScript Ed. 5 and later, you can and should use
instead. This has the additional advantage that the resulting
constructorproperty is not writable, enumerable, or configurable.The parent constructor will only be called if you call it explicitly, from
WeatherWidget, for example withSee also
Function.prototype.extend()in my JSX:object.js for how to generalize this. Using that code, it would becomeMy
Function.prototype.extend()takes an optional second argument with which you can easily augment the prototype ofWeatherWidgetinstances:would be equivalent to
You will still need to call the parent constructor explicitly in the child constructor, though; that part cannot reasonably be automated. But my
Function.prototype.extend()adds a_superproperty to theFunctioninstance which makes it easier:Other people have implemented similar extensions.