Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <pre><code>WeatherWidget.prototype = new Widget; </code></pre> <p>The <code>new</code> keyword calls <code>Widget</code> as a constructor and the return value is assigned to the <code>prototype</code> property. (If you would omit <code>new</code>, you would not call <code>Widget</code> unless you added an argument list, <code>()</code>. However, calling <code>Widget</code> that way might not be possible. It would certainly have the potential to <em>spoil the global namespace</em> if it is not strict mode code and the implementation is conforming to ECMAScript Ed. 5.x there, because then <code>this</code> in the constructor would refer to ECMAScript’s global object.)</p> <p>But this approach actually comes from a <a href="https://www.google.com/search?q=%22prototype+%3D+new%22&amp;filter=0" rel="nofollow noreferrer">really viral</a> <a href="http://docs.oracle.com/cd/E19957-01/816-6409-10/obj2.htm#1008404" rel="nofollow noreferrer"><em>bad example</em> in the old Netscape JavaScript 1.3 Guide</a> (mirrored at Oracle, formerly Sun).</p> <p>This way, your <code>WeatherWidget</code> instances will all inherit from the <em>same</em> <code>Widget</code> instance. The prototype chain will be:</p> <pre><code>[new WeatherWidget()] → [new Widget()] → [Widget.prototype] → … </code></pre> <p>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 <code>WeatherWidget</code> instances to <em>share among them</em> the <em>property values</em> they inherit from this <code>Widget</code> instance, and only <em>through it</em>, from <code>Widget.prototype</code>. 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.</p> <p>The proper way to implement class-based inheritance in these prototype-based languages is (originally devised by <a href="https://groups.google.com/group/comp.lang.javascript/msg/5d06e72e55d5bf11" rel="nofollow noreferrer">Lasse Reichstein Nielsen in <code>comp.lang.javascript</code> in 2003, for cloning objects</a>):</p> <pre><code>function Dummy () {} Dummy.prototype = Widget.prototype; WeatherWidget.prototype = new Dummy(); WeatherWidget.prototype.constructor = WeatherWidget; </code></pre> <p>The <code>constructor</code> prototype property should be fixed as well, so that your <code>WeatherWidget</code> instances <code>w</code> would have <code>w.constructor === WeatherWidget</code> as expected, and not <code>w.constructor === Widget</code>. However, be aware that it is enumerable afterwards.</p> <p>This way, <code>WeatherWidget</code> instances will inherit properties through the prototype chain, but will not share property values among them, because they inherit from <code>Widget.prototype</code> through <code>Dummy</code> which has no own properties:</p> <pre><code>[new WeatherWidget()] → [new Dummy()] → [Widget.prototype] → … </code></pre> <p>In implementations of ECMAScript Ed. 5 and later, you can and should use </p> <pre><code>WeatherWidget.prototype = Object.create(Widget.prototype, { constructor: {value: WeatherWidget} }); </code></pre> <p>instead. This has the additional advantage that the resulting <code>constructor</code> property is <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-8.6.1" rel="nofollow noreferrer">not writable, enumerable, or configurable</a>.</p> <p>The parent constructor will only be called if you call it explicitly, from <code>WeatherWidget</code>, for example with</p> <pre><code>function WeatherWidget (…) { Widget.apply(this, arguments); } </code></pre> <p>See also <a href="https://github.com/PointedEars/JSX/blob/master/object.js#L3457-L3709" rel="nofollow noreferrer"><code>Function.prototype.extend()</code></a> in my <a href="https://github.com/PointedEars/JSX/blob/master/object.js" rel="nofollow noreferrer">JSX:object.js</a> for how to generalize this. Using that code, it would become</p> <pre><code>WeatherWidget.extend(Widget); </code></pre> <p>My <code>Function.prototype.extend()</code> takes an optional second argument with which you can easily augment the prototype of <code>WeatherWidget</code> instances:</p> <pre><code>WeatherWidget.extend(Widget, { foo: 42, bar: "baz" }); </code></pre> <p>would be equivalent to</p> <pre><code>WeatherWidget.extend(Widget); WeatherWidget.prototype.foo = 42; WeatherWidget.prototype.bar = "baz"; </code></pre> <p>You will still need to call the parent constructor explicitly in the child constructor, though; that part cannot reasonably be automated. But my <code>Function.prototype.extend()</code> adds a <code>_super</code> property to the <code>Function</code> instance which makes it easier:</p> <pre><code>function WeatherWidget (…) { WeatherWidget._super.apply(this, arguments); } </code></pre> <p>Other people have implemented similar extensions.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload