<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Higher-Order &#187; parasitic inheritance</title>
	<atom:link href="http://blog.higher-order.net/category/parasitic-inheritance/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.higher-order.net</link>
	<description>topics: functional programming, concurrency, web-development, REST, dynamic languages</description>
	<lastBuildDate>Mon, 19 Jul 2010 06:45:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>JavaScript parasitic inheritance, power constructors and instanceof.</title>
		<link>http://blog.higher-order.net/2008/02/21/javascript-parasitic-inheritance-power-constructors-and-instanceof/</link>
		<comments>http://blog.higher-order.net/2008/02/21/javascript-parasitic-inheritance-power-constructors-and-instanceof/#comments</comments>
		<pubDate>Thu, 21 Feb 2008 15:29:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[instanceof]]></category>
		<category><![CDATA[parasitic inheritance]]></category>
		<category><![CDATA[power constructors]]></category>

		<guid isPermaLink="false">http://blog.higher-order.net/2008/02/21/javascript-parasitic-inheritance-power-constructors-and-instanceof/</guid>
		<description><![CDATA[Abstract. This posting shows how one can make Crockford&#8217;s power constructor functions play nicely with the JavaScript keyword &#8216;instanceof.&#8217; [update: March 18, 2008. I asked Crockford what he thinks about this pattern, and he actually discourages the use of 'instanceof' -- instead, he prefers to "... rely instead on good design and polymorphism."] The inheritance [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-weight: bold;">Abstract</span>. This posting shows how one can make Crockford&#8217;s power constructor functions play nicely with the JavaScript keyword &#8216;instanceof.&#8217;</p>
<p>[<em>update: March 18, 2008.</em> I asked Crockford what he thinks about this pattern, and he actually discourages the use of 'instanceof' -- instead, he prefers to "... rely instead on good design and polymorphism."]</p>
<p>The inheritance model of JavaScript is based on a combination of the &#8216;new&#8217; keyword and the prototype property of (constructor) functions. JavaScript Guru Douglas Crockford (aka &#8216;Yoda&#8217;) argues that this model (which he calls pseudo-classical) is awkward. Instead, he proposes an elegant, powerful and simple model (parasitic inheritance), using so-called power constructor functions. Note, familiarity with the above concepts is necessary for complete understanding of this post [and something that every web developer should know anyway <img src='http://blog.higher-order.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> ].</p>
<p>The advantages of power constructor functions include support for private, shared and public variables as well as simplicty (avoiding new and prototype). There is a mismatch, however, between constructors and the JavaScript keyword, <span style="font-family: courier new;">instanceof</span>. Consider the following example:</p>
<pre><tt><span class="comment">//recall that the object function creates a new object which has</span>
<span class="comment">//the input object, o, as its prototype</span>
<span class="keyword">var</span><span class="normal"> object </span><span class="symbol">=</span><span class="normal"> </span><span class="symbol">(</span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">     </span><span class="keyword">function</span><span class="normal"> </span><span class="function">F</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{}</span>
<span class="normal">     </span><span class="keyword">return</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">(</span><span class="normal">o</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">         F</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="normal"> </span><span class="symbol">=</span><span class="normal"> o</span><span class="symbol">;</span>
<span class="normal">         </span><span class="keyword">return</span><span class="normal"> </span><span class="keyword">new</span><span class="normal"> </span><span class="function">F</span><span class="symbol">();</span>
<span class="normal">     </span><span class="cbracket">}</span><span class="symbol">;</span>
<span class="cbracket">}</span><span class="symbol">)();</span><span class="comment">//included for completeness.</span>
<span class="keyword">var</span><span class="normal"> OriginalPerson </span><span class="symbol">=</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">   sayHello</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="cbracket">{</span>
<span class="normal">      </span><span class="keyword">return</span><span class="normal"> </span><span class="string">"Hello, my name is "</span><span class="symbol">+</span><span class="keyword">this</span><span class="symbol">.</span><span class="function">getName</span><span class="symbol">();</span>
<span class="normal">   </span><span class="cbracket">}</span><span class="symbol">,</span>
<span class="normal">   getName</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="cbracket">{</span><span class="keyword">return</span><span class="normal"> </span><span class="string">'Adam'</span><span class="symbol">;</span><span class="cbracket">}</span>
<span class="cbracket">}</span><span class="symbol">;</span>

<span class="keyword">function</span><span class="normal"> </span><span class="function">Person</span><span class="symbol">(</span><span class="normal">name</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">  </span><span class="keyword">var</span><span class="normal"> p </span><span class="symbol">=</span><span class="normal"> </span><span class="function">object</span><span class="symbol">(</span><span class="normal">OriginalPerson</span><span class="symbol">);</span>
<span class="normal">  p</span><span class="symbol">.</span><span class="normal">getName </span><span class="symbol">=</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span><span class="keyword">return</span><span class="normal"> name</span><span class="symbol">;</span><span class="cbracket">}</span><span class="symbol">;</span>
<span class="normal">  </span><span class="keyword">return</span><span class="normal"> p</span><span class="symbol">;</span>
<span class="cbracket">}</span>

<span class="keyword">function</span><span class="normal"> </span><span class="function">Guru</span><span class="symbol">(</span><span class="normal">name</span><span class="symbol">,</span><span class="normal">topic</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">  </span><span class="keyword">var</span><span class="normal"> g </span><span class="symbol">=</span><span class="normal"> </span><span class="function">object</span><span class="symbol">(</span><span class="function">Person</span><span class="symbol">(</span><span class="normal">name</span><span class="symbol">));</span><span class="comment">//Technically we don't need object(.) here</span>
<span class="normal">  g</span><span class="symbol">.</span><span class="normal">getTopic </span><span class="symbol">=</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span><span class="keyword">return</span><span class="normal"> topic</span><span class="symbol">;</span><span class="cbracket">}</span><span class="symbol">;</span>
<span class="normal">  </span><span class="keyword">return</span><span class="normal"> g</span><span class="symbol">;</span>
<span class="cbracket">}</span>

<span class="keyword">var</span><span class="normal"> karl </span><span class="symbol">=</span><span class="normal"> </span><span class="function">Person</span><span class="symbol">(</span><span class="string">'Karl'</span><span class="symbol">);</span>
<span class="keyword">var</span><span class="normal"> crockford </span><span class="symbol">=</span><span class="normal"> </span><span class="function">Guru</span><span class="symbol">(</span><span class="string">'Douglas'</span><span class="symbol">,</span><span class="string">'JavaScript'</span><span class="symbol">);</span>

<span class="normal">karl </span><span class="keyword">instanceof</span><span class="normal"> Person</span><span class="symbol">;</span><span class="comment">//&amp;lt;- false </span>
<span class="normal">crockford </span><span class="keyword">instanceof</span><span class="normal"> Guru</span><span class="symbol">;</span><span class="comment">//&amp;lt;- false</span>
</tt></pre>
<p>Hmm&#8230; Clearly, any environment that makes <span style="font-family: courier new;">crockford instanceof Guru</span> evaluate to <span style="font-family: courier new;">false</span> must be getting something wrong!</p>
<p>In general, one has to do <span style="font-style:italic;">something</span> to make super-constructors work with <span style="font-family: courier new;">instanceof</span>. The expression <span style="font-family: courier new;">exp1 instanceof exp2</span> where <span style="font-family: courier new;">exp1,exp2</span> are JS expressions (<span style="font-family: courier new;">exp2</span> must evaluate to a function and <span style="font-family: courier new;">exp1</span> should evaluate to an object) works with following semantics:</p>
<p>First <span style="font-family: courier new;">exp1</span> is evaluated, say, to <span style="font-family: courier new;">o</span> then<br />
<span style="font-family: courier new;">exp2</span> is evaluated, say, to <span style="font-family: courier new;">f</span>. If <span style="font-family: courier new;">o</span> is an object and <span style="font-family: courier new;">f</span> is a function, the entire expression evaluates to true only if following <span style="font-family: courier new;">o</span>&#8216;s [[prototype]] chain, we can reach <span style="font-family: courier new;">f.prototype</span>.</p>
<p>This means that to make this work, we must ensure that the object created has <span style="font-family: courier new;">Person.prototype</span> or <span style="font-family: courier new;">Guru.prototype</span> in its prototype chain.</p>
<p>What I would really like to end up with at the end of this blog entry, is to be able to write code similar to:</p>
<pre><tt><span class="keyword">var</span><span class="normal"> OriginalPerson </span><span class="symbol">=</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">   sayHello</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="cbracket">{</span>
<span class="normal">      </span><span class="keyword">return</span><span class="normal"> </span><span class="string">"Hello, my name is "</span><span class="symbol">+</span><span class="keyword">this</span><span class="symbol">.</span><span class="function">getName</span><span class="symbol">();</span>
<span class="normal">   </span><span class="cbracket">}</span><span class="symbol">,</span>
<span class="normal">   getName</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="cbracket">{</span><span class="keyword">return</span><span class="normal"> </span><span class="string">'Adam'</span><span class="symbol">;</span><span class="cbracket">}</span>
<span class="cbracket">}</span><span class="symbol">;</span>

<span class="keyword">var</span><span class="normal"> Person </span><span class="symbol">=</span><span class="normal"> OriginalPerson</span><span class="symbol">.</span><span class="function">parasite</span><span class="symbol">(</span><span class="keyword">function</span><span class="symbol">(</span><span class="normal">Host</span><span class="symbol">,</span><span class="normal">name</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">  </span><span class="keyword">var</span><span class="normal"> p </span><span class="symbol">=</span><span class="normal"> </span><span class="function">object</span><span class="symbol">(</span><span class="function">Host</span><span class="symbol">());</span>
<span class="normal">  p</span><span class="symbol">.</span><span class="normal">getName </span><span class="symbol">=</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span><span class="keyword">return</span><span class="normal"> name</span><span class="symbol">;</span><span class="cbracket">}</span><span class="symbol">;</span>
<span class="normal">  </span><span class="keyword">return</span><span class="normal"> p</span><span class="symbol">;</span>
<span class="cbracket">}</span><span class="symbol">);</span>

<span class="keyword">var</span><span class="normal"> Guru </span><span class="symbol">=</span><span class="normal"> Person</span><span class="symbol">.</span><span class="function">parasite</span><span class="symbol">(</span><span class="keyword">function</span><span class="symbol">(</span><span class="normal">Host</span><span class="symbol">,</span><span class="normal"> name</span><span class="symbol">,</span><span class="normal">topic</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">  </span><span class="keyword">var</span><span class="normal"> g </span><span class="symbol">=</span><span class="normal"> </span><span class="function">object</span><span class="symbol">(</span><span class="function">Host</span><span class="symbol">(</span><span class="normal">name</span><span class="symbol">));</span>
<span class="normal">  g</span><span class="symbol">.</span><span class="normal">getTopic </span><span class="symbol">=</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span><span class="keyword">return</span><span class="normal"> topic</span><span class="symbol">;</span><span class="cbracket">}</span><span class="symbol">;</span>
<span class="normal">  </span><span class="keyword">return</span><span class="normal"> g</span><span class="symbol">;</span>
<span class="cbracket">}</span><span class="symbol">);</span>

<span class="function">Guru</span><span class="symbol">(</span><span class="string">'Douglas Crockford'</span><span class="symbol">,</span><span class="string">'JavaScript'</span><span class="symbol">)</span><span class="normal"> </span><span class="keyword">instanceof</span><span class="normal"> Guru</span><span class="symbol">;</span><span class="comment">//&amp;lt;-- true </span>
<span class="function">Guru</span><span class="symbol">(</span><span class="string">'Douglas Crockford'</span><span class="symbol">,</span><span class="string">'JavaScript'</span><span class="symbol">)</span><span class="normal"> </span><span class="keyword">instanceof</span><span class="normal"> Person</span><span class="symbol">;</span><span class="comment">//&amp;lt;-- true</span>
</tt></pre>
<p>The extra parameter <span style="font-family: courier new;">Host</span> is supposed to represent the &#8220;Host&#8221; of the parasite (i.e., Person in the case of Guru), the idea being that the <span style="font-family: courier new;">parasite</span> function will somehow &#8216;wrap&#8217; the <span style="font-family: courier new;">Person</span> function to set it up so that &#8216;instanceof&#8217; works, and then finally feed this wrapped function to the parasite (via the Host variable). I won&#8217;t be able to write the code exactly as above, but we will get close&#8230; Anyway, hopefully this will make more sense very soon!</p>
<p><span style="font-weight:bold;">We will get there in two steps</span>. First we code it up manually (so to speak) and secondly we will do the meta-programming with <span style="font-family: courier new;">parasite</span>.</p>
<p>Incidentally, we can exploit Crockford&#8217;s &#8216;shared secrets&#8217; technique to get the prototype chain working. Consider the following code.</p>
<pre><tt><span class="keyword">function</span><span class="normal"> </span><span class="function">Person</span><span class="symbol">(</span><span class="normal">name</span><span class="symbol">,</span><span class="normal"> proto</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">  </span><span class="keyword">var</span><span class="normal"> p </span><span class="symbol">=</span><span class="normal"> </span><span class="function">object</span><span class="symbol">(</span><span class="normal">proto </span><span class="symbol">||</span><span class="normal"> Person</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="symbol">);</span>
<span class="normal">  p</span><span class="symbol">.</span><span class="normal">getName </span><span class="symbol">=</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span><span class="keyword">return</span><span class="normal"> name</span><span class="symbol">;</span><span class="cbracket">}</span><span class="symbol">;</span>
<span class="normal">  </span><span class="keyword">return</span><span class="normal"> p</span><span class="symbol">;</span>
<span class="cbracket">}</span>
<span class="normal">Person</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="normal"> </span><span class="symbol">=</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">   sayHello</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="cbracket">{</span>
<span class="normal">      </span><span class="keyword">return</span><span class="normal"> </span><span class="string">"Hello, my name is "</span><span class="symbol">+</span><span class="keyword">this</span><span class="symbol">.</span><span class="function">getName</span><span class="symbol">();</span>
<span class="normal">   </span><span class="cbracket">}</span><span class="symbol">,</span>
<span class="normal">   getName</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="cbracket">{</span><span class="keyword">return</span><span class="normal"> </span><span class="string">'Adam'</span><span class="symbol">;</span><span class="cbracket">}</span>
<span class="cbracket">}</span><span class="symbol">;</span>
<span class="function">Person</span><span class="symbol">(</span><span class="string">'Karl'</span><span class="symbol">)</span><span class="normal"> </span><span class="keyword">instanceof</span><span class="normal"> Person</span><span class="symbol">;</span><span class="comment">//&amp;lt;-- true</span>
</tt></pre>
<p>The key here is the statement: <span style="font-family: courier new;">object(proto || Person.prototype)</span>. This ensures that the object created has <span style="font-family: courier new;">Person.prototype</span> in its [[prototype]] chain. The <span style="font-family: courier new;">proto ||</span>-part is intended to be used as a &#8216;shared secret&#8217; between a parasite &#8216;sub type&#8217;/'sub power constructor&#8217;; the invariant is that <span style="font-family: courier new;">proto || Person.prototype</span> will always denote an object which is <span style="font-family: courier new;">Person.prototype</span> or has it in its prototype chain. It can be used as follows:</p>
<pre><tt><span class="keyword">function</span><span class="normal"> </span><span class="function">Guru</span><span class="symbol">(</span><span class="normal">name</span><span class="symbol">,</span><span class="normal">topic</span><span class="symbol">,</span><span class="normal">proto</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">  </span><span class="keyword">var</span><span class="normal"> g </span><span class="symbol">=</span><span class="normal"> </span><span class="function">object</span><span class="symbol">(</span><span class="function">Person</span><span class="symbol">(</span><span class="normal">name</span><span class="symbol">,</span><span class="normal"> proto </span><span class="symbol">||</span><span class="normal"> Guru</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="symbol">));</span>
<span class="normal">  g</span><span class="symbol">.</span><span class="normal">getTopic </span><span class="symbol">=</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span><span class="keyword">return</span><span class="normal"> topic</span><span class="symbol">;</span><span class="cbracket">}</span><span class="symbol">;</span>
<span class="normal">  </span><span class="keyword">return</span><span class="normal"> g</span><span class="symbol">;</span>
<span class="cbracket">}</span>
<span class="normal">Guru</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="normal"> </span><span class="symbol">=</span><span class="normal"> </span><span class="function">object</span><span class="symbol">(</span><span class="normal">Person</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="symbol">);</span>
<span class="function">Guru</span><span class="symbol">(</span><span class="string">'Douglas Crockford'</span><span class="symbol">,</span><span class="string">'JavaScript'</span><span class="symbol">)</span><span class="normal"> </span><span class="keyword">instanceof</span><span class="normal"> Guru</span><span class="symbol">;</span><span class="comment">//&amp;lt;-- true</span>
<span class="function">Guru</span><span class="symbol">(</span><span class="string">'Douglas Crockford'</span><span class="symbol">,</span><span class="string">'JavaScript'</span><span class="symbol">)</span><span class="normal"> </span><span class="keyword">instanceof</span><span class="normal"> Person</span><span class="symbol">;</span><span class="comment">//&amp;lt;-- true</span>
</tt></pre>
<p>Actually, I feel some pleasure in the assignments:</p>
<pre><tt><span class="normal">Person</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="normal"> </span><span class="symbol">=</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">   sayHello</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="cbracket">{</span>
<span class="normal">      </span><span class="keyword">return</span><span class="normal"> </span><span class="string">"Hello, my name is "</span><span class="symbol">+</span><span class="keyword">this</span><span class="symbol">.</span><span class="function">getName</span><span class="symbol">();</span>
<span class="normal">   </span><span class="cbracket">}</span><span class="symbol">,</span>
<span class="normal">   getName</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="cbracket">{</span><span class="keyword">return</span><span class="normal"> </span><span class="string">'Adam'</span><span class="symbol">;</span><span class="cbracket">}</span>
<span class="cbracket">}</span><span class="symbol">;</span>
</tt></pre>
<p>and <span style="font-family: courier new;">Guru.prototype = object(Person.prototype);</span>: Intutively, these objects are the &#8216;prototypes&#8217; of the objects created by the power constructors, so it feels natural to make this assignment.</p>
<p>So far so good &#8211; we have instanceof working with power-constructors, but we can do better. The problem now is to do the meta-programming that will handle the &#8216;secret-sharing&#8217; behind the scenes.</p>
<p>In this example, we will enhance <span style="font-family: courier new;">Object.prototype</span> and <span style="font-family: courier new;">Function.prototype</span>. For simplicity I&#8217;ve introduced the constraint that all power-constructor functions should take only one argument [however, I'm convinced this can be generalized to more than one argument].</p>
<p><strong>Note, slightly off topic here&#8230;</strong><br />
In either case, I&#8217;ve developed at taste for single-argument functions. Consider:</p>
<pre><tt><span class="comment">/** power-constructer for Guru objects </span>
<span class="comment">  *</span><span class="type">@param</span><span class="comment"> conf {Object} a configuration object with properties:</span>
<span class="comment">  * name and topic</span>
<span class="comment">  * </span><span class="type">@return</span><span class="comment"> a Guru object with name: conf.name and topic: conf.topic.</span>
<span class="comment">  */</span>
<span class="keyword">function</span><span class="normal"> </span><span class="function">Guru</span><span class="symbol">(</span><span class="normal">conf</span><span class="symbol">)</span><span class="cbracket">{</span>
<span class="normal">  </span><span class="keyword">var</span><span class="normal"> g </span><span class="symbol">=</span><span class="normal"> </span><span class="function">object</span><span class="symbol">(</span><span class="function">Person</span><span class="symbol">(</span><span class="normal">conf</span><span class="symbol">)),</span>
<span class="normal">      t </span><span class="symbol">=</span><span class="normal"> conf</span><span class="symbol">.</span><span class="normal">topic </span><span class="symbol">||</span><span class="normal"> </span><span class="string">'none'</span><span class="symbol">;</span>
<span class="normal">  g</span><span class="symbol">.</span><span class="normal">getTopic </span><span class="symbol">=</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="cbracket">{</span><span class="keyword">return</span><span class="normal"> t</span><span class="symbol">;</span><span class="cbracket">}</span><span class="symbol">;</span>
<span class="normal">  </span><span class="keyword">return</span><span class="normal"> g</span><span class="symbol">;</span>
<span class="cbracket">}</span>
<span class="function">Guru</span><span class="symbol">(</span><span class="cbracket">{</span><span class="normal">name</span><span class="symbol">:</span><span class="string">'Yoda'</span><span class="symbol">,</span><span class="normal"> topic</span><span class="symbol">:</span><span class="string">'JavaScript'</span><span class="cbracket">}</span><span class="symbol">);</span>
</tt></pre>
<p>The disadvantage is that there is slightly more code to write. The advantages are (1) readability: <span style="font-family: courier new;">Guru({name:&#8217;Yoda&#8217;, topic:&#8217;JavaScript&#8217;})</span> can be read without having to consult the constructor function about which argument is the name and which is the topic; (2) optional/default arguments: you can leave out either of the arguments: <span style="font-family: courier new;">Guru({name:&#8217;Yoda&#8217;})</span> or <span style="font-family: courier new;">Guru({topic:&#8217;JavaScript&#8217;})</span> are both valid (in the multiple arg constructor with name as the first parameter, you&#8217;d have to write <span style="font-family: courier new;">Guru(&#8216;Yoda&#8217;)</span> (which is fine), and <span style="font-family: courier new;">Guru(undefined,&#8217;JavaScript&#8217;)</span> (which is not).</p>
<p><strong>Back on track</strong><br />
The following is my implementation. I extend <span style="font-family: courier new;">Object.prototype</span> and <span style="font-family: courier new;">Function.prototype</span> so that we can write:</p>
<pre><tt><span class="keyword">var</span><span class="normal"> OriginalPerson </span><span class="symbol">=</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">   sayHello</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="cbracket">{</span>
<span class="normal">      </span><span class="keyword">return</span><span class="normal"> </span><span class="string">"Hello, my name is "</span><span class="symbol">+</span><span class="keyword">this</span><span class="symbol">.</span><span class="function">getName</span><span class="symbol">();</span>
<span class="normal">   </span><span class="cbracket">}</span><span class="symbol">,</span>
<span class="normal">   getName</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="cbracket">{</span><span class="keyword">return</span><span class="normal"> </span><span class="string">'Adam'</span><span class="symbol">;</span><span class="cbracket">}</span>
<span class="cbracket">}</span><span class="symbol">;</span>

<span class="keyword">var</span><span class="normal"> Person </span><span class="symbol">=</span><span class="normal"> OriginalPerson</span><span class="symbol">.</span><span class="function">parasite</span><span class="symbol">(</span><span class="keyword">function</span><span class="symbol">(</span><span class="normal">Host</span><span class="symbol">,</span><span class="normal"> conf</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">  </span><span class="keyword">var</span><span class="normal"> p </span><span class="symbol">=</span><span class="normal"> </span><span class="function">object</span><span class="symbol">(</span><span class="function">Host</span><span class="symbol">()),</span>
<span class="normal">      name </span><span class="symbol">=</span><span class="normal"> conf</span><span class="symbol">.</span><span class="normal">name </span><span class="symbol">||</span><span class="normal"> </span><span class="string">'Anonymous'</span><span class="symbol">;</span>
<span class="normal">  p</span><span class="symbol">.</span><span class="normal">getName </span><span class="symbol">=</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span><span class="keyword">return</span><span class="normal"> name</span><span class="symbol">;</span><span class="cbracket">}</span><span class="symbol">;</span>
<span class="normal">  </span><span class="keyword">return</span><span class="normal"> p</span><span class="symbol">;</span>
<span class="cbracket">}</span><span class="symbol">);</span>

<span class="keyword">var</span><span class="normal"> Guru </span><span class="symbol">=</span><span class="normal"> Person</span><span class="symbol">.</span><span class="function">parasite</span><span class="symbol">(</span><span class="keyword">function</span><span class="symbol">(</span><span class="normal">Host</span><span class="symbol">,</span><span class="normal"> conf</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">  </span><span class="keyword">var</span><span class="normal"> g </span><span class="symbol">=</span><span class="normal"> </span><span class="function">object</span><span class="symbol">(</span><span class="function">Host</span><span class="symbol">(</span><span class="normal">conf</span><span class="symbol">)),</span>
<span class="normal">      topic </span><span class="symbol">=</span><span class="normal"> conf</span><span class="symbol">.</span><span class="normal">topic </span><span class="symbol">||</span><span class="normal"> </span><span class="string">'none'</span><span class="symbol">;</span>
<span class="normal">  g</span><span class="symbol">.</span><span class="normal">getTopic </span><span class="symbol">=</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span><span class="keyword">return</span><span class="normal"> topic</span><span class="symbol">;</span><span class="cbracket">}</span>
<span class="normal">  </span><span class="keyword">return</span><span class="normal"> g</span><span class="symbol">;</span>
<span class="cbracket">}</span><span class="symbol">);</span>
<span class="keyword">var</span><span class="normal"> h </span><span class="symbol">=</span><span class="normal"> </span><span class="function">Guru</span><span class="symbol">(</span><span class="cbracket">{</span>
<span class="normal"> name</span><span class="symbol">:</span><span class="normal"> </span><span class="string">'Douglas Crockford'</span><span class="symbol">,</span>
<span class="normal"> topic</span><span class="symbol">:</span><span class="normal"> </span><span class="string">'JavaScript'</span>
<span class="cbracket">}</span><span class="symbol">);</span>
<span class="normal">h </span><span class="keyword">instanceof</span><span class="normal"> Guru</span><span class="symbol">;</span><span class="comment">//&lt;-- true</span>
<span class="normal">h </span><span class="keyword">instanceof</span><span class="normal"> Person</span><span class="symbol">;</span><span class="comment">//&lt;-- true</span>
</tt></pre>
<p>I&#8217;ve implemented it as follows (with comments):</p>
<pre><tt><span class="normal">Object</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="symbol">.</span><span class="normal">parasite </span><span class="symbol">=</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">(</span><span class="normal">parasite</span><span class="symbol">)</span><span class="cbracket">{</span>
<span class="normal">    </span><span class="comment">/* This is the function returned as the result</span>
<span class="comment">       of this call; it represents a wrapper for the</span>
<span class="comment">       function in parameter parasite. wrapper will simply</span>
<span class="comment">       call the parasite function, but supplying a Host function</span>
<span class="comment">       as the first argument. If wrapper is called with proto === undefined</span>
<span class="comment">       then the Host function will create an object with its prototype === this,</span>
<span class="comment">       otherwise an object with prototype === proto is created (this lets</span>
<span class="comment">       sub-parasites supply the proto parameter).</span>
<span class="comment">    */</span>
<span class="normal">    </span><span class="keyword">function</span><span class="normal"> </span><span class="function">wrapper</span><span class="symbol">(</span><span class="normal">conf</span><span class="symbol">,</span><span class="normal">proto</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">        </span><span class="keyword">var</span><span class="normal"> p </span><span class="symbol">=</span><span class="normal"> proto</span><span class="symbol">;</span><span class="comment">//Exercise why is this necessary?</span>
<span class="normal">        Array</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="symbol">.</span><span class="normal">splice</span><span class="symbol">.</span><span class="function">call</span><span class="symbol">(</span><span class="normal">arguments</span><span class="symbol">,</span><span class="number">0</span><span class="symbol">,</span><span class="number">0</span><span class="symbol">,</span><span class="keyword">function</span><span class="symbol">()</span><span class="cbracket">{</span>
<span class="normal">           </span><span class="keyword">return</span><span class="normal"> </span><span class="function">object</span><span class="symbol">(</span><span class="normal">p </span><span class="symbol">||</span><span class="normal"> wrapper</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="symbol">);</span>
<span class="normal">        </span><span class="cbracket">}</span><span class="symbol">);</span>
<span class="normal">        </span><span class="keyword">return</span><span class="normal"> parasite</span><span class="symbol">.</span><span class="function">apply</span><span class="symbol">(</span><span class="keyword">this</span><span class="symbol">,</span><span class="normal"> arguments</span><span class="symbol">);</span>
<span class="normal">    </span><span class="cbracket">}</span>
<span class="normal">    </span><span class="comment">/* it is important that wrapper.prototype is set to this object, both so that</span>
<span class="comment">       o instanceof wrapper works, and so that objects created with</span>
<span class="comment">       object(p || wrapper.prototype) above will inherit properties of this */</span>
<span class="normal">    wrapper</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="normal"> </span><span class="symbol">=</span><span class="normal"> </span><span class="keyword">this</span><span class="symbol">;</span>
<span class="normal">    </span><span class="keyword">return</span><span class="normal"> wrapper</span><span class="symbol">;</span>
<span class="cbracket">}</span><span class="symbol">;</span>
<span class="normal">Function</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="symbol">.</span><span class="normal">parasite </span><span class="symbol">=</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">(</span><span class="normal">parasite</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">    </span><span class="keyword">var</span><span class="normal"> host_cons </span><span class="symbol">=</span><span class="normal"> </span><span class="keyword">this</span><span class="symbol">;</span><span class="comment">//the constructor function for the host of parasite</span>

<span class="normal">    </span><span class="comment">/* Again, this function is the result of the computation. </span>
<span class="comment">       When called it splices a Host function on the 0'th pos in the arguments array.</span>
<span class="comment">       The Host function will call the host_cons and (important!) supplies an </span>
<span class="comment">       additional last argument (proto). If proto === undefined we are in the case</span>
<span class="comment">       where client code is calling wrapper, so we call the host_cons function</span>
<span class="comment">       supplying wrapper.prototype; if instead proto is provided we call host_cons</span>
<span class="comment">       with this object (this is the case where wrapper is called by a sub-parasite).</span>
<span class="comment">    */</span>
<span class="normal">    </span><span class="keyword">function</span><span class="normal"> </span><span class="function">wrapper</span><span class="symbol">(</span><span class="normal">conf</span><span class="symbol">,</span><span class="normal">proto</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">         </span><span class="keyword">var</span><span class="normal"> wrapper_this </span><span class="symbol">=</span><span class="normal"> </span><span class="keyword">this</span><span class="symbol">,</span>
<span class="normal">             p </span><span class="symbol">=</span><span class="normal"> proto</span><span class="symbol">;</span><span class="comment">//exercise: why?</span>
<span class="normal">         Array</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="symbol">.</span><span class="normal">splice</span><span class="symbol">.</span><span class="function">call</span><span class="symbol">(</span><span class="normal">arguments</span><span class="symbol">,</span><span class="number">0</span><span class="symbol">,</span><span class="number">0</span><span class="symbol">,</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">              Array</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="symbol">.</span><span class="normal">splice</span><span class="symbol">.</span><span class="function">call</span><span class="symbol">(</span><span class="normal">arguments</span><span class="symbol">,</span><span class="normal">arguments</span><span class="symbol">.</span><span class="normal">length</span><span class="symbol">,</span><span class="number">0</span><span class="symbol">,</span><span class="normal"> </span>
<span class="normal">                                              p </span><span class="symbol">||</span><span class="normal"> wrapper</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="symbol">);</span>
<span class="normal">              </span><span class="keyword">return</span><span class="normal"> host_cons</span><span class="symbol">.</span><span class="function">apply</span><span class="symbol">(</span><span class="normal">wrapper_this</span><span class="symbol">,</span><span class="normal">arguments</span><span class="symbol">);</span><span class="normal"> </span>
<span class="normal">         </span><span class="cbracket">}</span><span class="symbol">);</span>
<span class="normal">         </span><span class="keyword">return</span><span class="normal"> parasite</span><span class="symbol">.</span><span class="function">apply</span><span class="symbol">(</span><span class="keyword">this</span><span class="symbol">,</span><span class="normal"> arguments</span><span class="symbol">);</span>
<span class="normal">    </span><span class="cbracket">}</span>
<span class="normal">    </span><span class="comment">/* our prototype is an object which inherits properties from this.prototype,</span>
<span class="comment">       e.g., Guru.prototype inherits from Person.prototype.</span>
<span class="comment">    */</span>
<span class="normal">    wrapper</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="normal"> </span><span class="symbol">=</span><span class="normal"> </span><span class="function">object</span><span class="symbol">(</span><span class="keyword">this</span><span class="symbol">.</span><span class="keyword">prototype</span><span class="symbol">);</span>
<span class="normal">    </span><span class="keyword">return</span><span class="normal"> wrapper</span><span class="symbol">;</span>
<span class="cbracket">}</span><span class="symbol">;</span>
</tt></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.higher-order.net/2008/02/21/javascript-parasitic-inheritance-power-constructors-and-instanceof/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
