<br><br><div class="gmail_quote">On Fri, Oct 1, 2010 at 10:00 PM, Oliver Hunt <span dir="ltr">&lt;<a href="mailto:oliver@apple.com">oliver@apple.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im"><br>
On Oct 1, 2010, at 6:55 PM, Brendan Eich wrote:<br>
<br>
&gt; On Oct 1, 2010, at 6:24 PM, Oliver Hunt wrote:<br>
&gt;<br>
&gt;&gt; I really don&#39;t like the idea of using proxies simply to essentially create an array with a custom prototype.<br>
&gt;<br>
&gt; Implement proxies, then we&#39;ll talk :-P.<br>
&gt;<br>
&gt;<br>
&gt;&gt; My understanding of what is wanted (in terms of subtyping an array) is an ability to have something like<br>
&gt;&gt;<br>
&gt;&gt; var arr = new MyArray()<br>
&gt;&gt;<br>
&gt;&gt; Where &#39;new MyArray&#39; behaves in essentially the same manner as &#39;new Array&#39;, however it produces an object along the lines of<br>
&gt;&gt;<br>
&gt;&gt; &lt;an array instance&gt; &lt;- &lt;a custom prototype&gt; &lt;- &lt;array prototype&gt;<br>
&gt;<br>
&gt; I don&#39;t think the use-case is satisfied by a direct Array instance, whatever its proto. That&#39;s the rub.<br>
<br>
</div>What part of the use case is not covered? From reading the blog post (which suggests something similar to this) kangax says the problem with this solution is the use of the non-standard __proto__, not that it doesn&#39;t achieve the desired result<br>
</blockquote><div><br></div><div>Object.create([]) doesn&#39;t solve the problem of subclassing an array, since created object is still a plain Object object and so has [[Get]] and [[Put]] that act like Object&#39;s ones, not Array ones.</div>
<div><br></div><div>var o = Object.create([]);</div><div>o[2] = &#39;x&#39;;</div><div>o.length; /* 0, not 3 as it should be */</div><div><br></div><div>o.length = 0;</div><div>o[2]; /* &quot;x&quot;, not undefined as it should be */</div>
<div><br></div><div>In ES3 (w/o extensions) you can&#39;t do much about it, but in ES5 it&#39;s possible to fiddle with length getter/setter to make object act like an array (the performance of such implementation turns out to be incredibly slow, for obvious reasons).</div>
<div><br></div><div>So now when you solved &quot;magic&quot; length property (considering that we&#39;re in ES5), and have a plain Object object with [[Prototype]] referencing Array.prototype, you still have immutable [[Class]]. So Array.isArray would return false for this pseudo-array object (it could be somehow overwritten to account for it, but this is kind of getting too far); and then there are places in spec, where wrong [[Class]] (&quot;Object&quot;, not &quot;Array&quot;) will make for a completely different outcome. For example, JSON.stringify:</div>
<div><br></div><div>var o = Object.create([]);</div><div>o[2] = &#39;x&#39;;</div><div><br></div><div>JSON.stringify(o); // &quot;{&quot;2&quot;:&quot;x&quot;,&quot;length&quot;:0}&quot; not[null,null,&quot;x&quot;]</div>
<div><br></div><div>Settable [[Prototype]] helps because you can just create an array object, then inject something into its prototype chain (right before Array.prototype). And that extra object can have any methods you wish on subarray instances  all without polluting global Array.prototype.</div>
<div><br></div><div>[...]</div><div><br></div><div>--</div><div>kangax</div></div>