<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="https://mg.to" xmlns:dc="https://purl.org/dc/elements/1.1/">
<channel>
 <title>mg.to - Prototype vs. Web 2.0 - Comments</title>
 <link>https://mg.to/2006/05/20/prototype-vs-web-2-0</link>
 <description>Comments for &quot;Prototype vs. Web 2.0&quot;</description>
 <language>en</language>
<item>
 <title>Prototype vs. Web 2.0</title>
 <link>https://mg.to/2006/05/20/prototype-vs-web-2-0</link>
 <description>&lt;p&gt;In yesterday&amp;#8217;s &lt;a href=&quot;https://ajaxian.com/&quot;&gt;Ajaxian&lt;/a&gt;, Rob Sanheim &lt;a href=&quot;https://ajaxian.com/archives/javascript-associative-arrays-considered-harmful&quot;&gt;reviews&lt;/a&gt; a post that explains why programmers should not use JavaScript&amp;#8217;s &lt;code&gt;Array&lt;/code&gt; type for associative arrays. &lt;code&gt;Array&lt;/code&gt; objects should be used only for integer-indexed arrays. The correct type for an associative array in JavaScript is &lt;code&gt;Object&lt;/code&gt;, not &lt;code&gt;Array&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Rob is right, of course. A JavaScript &lt;code&gt;Object&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; an associative array or hash table. An &lt;code&gt;Array&lt;/code&gt; is also an &lt;code&gt;Object&lt;/code&gt; (in fact, &lt;code&gt;typeof [] == &#039;object&#039;&lt;/code&gt;), but it&amp;#8217;s really meant for arrays indexed by integers.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s an easy mistake to make, especially for someone who has come from a language where the associative array type &lt;em&gt;is&lt;/em&gt; called an array. I don&amp;#8217;t think I&amp;#8217;ve made this particular mistake, but I have made a similar one. I used to use the &lt;code&gt;for-in&lt;/code&gt; loop because I liked its simplicity:&lt;/p&gt;

&lt;div style=&quot;padding: 5px !important; border: 1px solid rgb(253,187,134) !important; background-color: rgb(255,253,245) !important; font-family: Verdana,sans-serif !important;&quot;&gt;&lt;div style=&quot;background-color: rgb(255,250,238) !important;&quot;&gt;&lt;div class=&quot;geshi-javascript&quot;&gt;&lt;div style=&quot;background-color:rgb(255,234,216);&quot;&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; a = &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;a&#039;&lt;/span&gt;, &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;b&#039;&lt;/span&gt;, &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;c&#039;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;color: #C00000;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; i &lt;span style=&quot;color: #C00000;&quot;&gt;in&lt;/span&gt; a &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color:rgb(255,234,216);&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #000066;&quot;&gt;alert&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#40;&lt;/span&gt; a&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#91;&lt;/span&gt;i&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#41;&lt;/span&gt;;&amp;nbsp; &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That looks better to me than the C-style loop:&lt;/p&gt;

&lt;div style=&quot;padding: 5px !important; border: 1px solid rgb(253,187,134) !important; background-color: rgb(255,253,245) !important; font-family: Verdana,sans-serif !important;&quot;&gt;&lt;div style=&quot;background-color: rgb(255,250,238) !important;&quot;&gt;&lt;div class=&quot;geshi-javascript&quot;&gt;&lt;div style=&quot;background-color:rgb(255,234,216);&quot;&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; a = &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;a&#039;&lt;/span&gt;, &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;b&#039;&lt;/span&gt;, &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;c&#039;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;color: #C00000;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; i = &lt;span style=&quot;color: #CC0000;&quot;&gt;0&lt;/span&gt;;&amp;nbsp; i &amp;lt; a.&lt;span style=&quot;color: #006600;&quot;&gt;length&lt;/span&gt;;&amp;nbsp; i++ &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color:rgb(255,234,216);&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #000066;&quot;&gt;alert&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#40;&lt;/span&gt; a&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#91;&lt;/span&gt;i&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#41;&lt;/span&gt;;&amp;nbsp; &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;for-in&lt;/code&gt; loop works on an &lt;code&gt;Array&lt;/code&gt; because an &lt;code&gt;Array&lt;/code&gt; is an &lt;code&gt;Object&lt;/code&gt;, but that also means it &lt;em&gt;treats&lt;/em&gt; the &lt;code&gt;Array&lt;/code&gt; as an &lt;code&gt;Object&lt;/code&gt;. It enumerates the array elements because they are also properties of the underlying &lt;code&gt;Object&lt;/code&gt;, but it doesn&amp;#8217;t necessarily enumerate them in order by index:&lt;/p&gt;

&lt;div style=&quot;padding: 5px !important; border: 1px solid rgb(253,187,134) !important; background-color: rgb(255,253,245) !important; font-family: Verdana,sans-serif !important;&quot;&gt;&lt;div style=&quot;background-color: rgb(255,250,238) !important;&quot;&gt;&lt;div class=&quot;geshi-javascript&quot;&gt;&lt;div style=&quot;background-color:rgb(255,234,216);&quot;&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; a = &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;&lt;/div&gt;
a&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #CC0000;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;b&#039;&lt;/span&gt;;&lt;br /&gt;
&lt;div style=&quot;background-color:rgb(255,234,216);&quot;&gt;a&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #CC0000;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;c&#039;&lt;/span&gt;;&lt;br /&gt;&lt;/div&gt;
a&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #CC0000;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;a&#039;&lt;/span&gt;;&lt;br /&gt;
&lt;div style=&quot;background-color:rgb(255,234,216);&quot;&gt;&lt;span style=&quot;color: #C00000;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; i &lt;span style=&quot;color: #C00000;&quot;&gt;in&lt;/span&gt; a &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #000066;&quot;&gt;alert&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#40;&lt;/span&gt; a&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#91;&lt;/span&gt;i&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#41;&lt;/span&gt;;&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the browsers I tried, this code alerts the letters in the order that they were added to the array, not in index order. But there&amp;#8217;s no guarantee about that order either, because the &lt;code&gt;for-in&lt;/code&gt; loop doesn&amp;#8217;t promise any particular order of enumeration.&lt;/p&gt;

&lt;p&gt;Worse, &lt;code&gt;for-in&lt;/code&gt; also enumerates any extra properties or methods added to the array:&lt;/p&gt;

&lt;div style=&quot;padding: 5px !important; border: 1px solid rgb(253,187,134) !important; background-color: rgb(255,253,245) !important; font-family: Verdana,sans-serif !important;&quot;&gt;&lt;div style=&quot;background-color: rgb(255,250,238) !important;&quot;&gt;&lt;div class=&quot;geshi-javascript&quot;&gt;&lt;div style=&quot;background-color:rgb(255,234,216);&quot;&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; a = &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;a&#039;&lt;/span&gt;, &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;b&#039;&lt;/span&gt;, &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;c&#039;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;&lt;/div&gt;
a.&lt;span style=&quot;color: #000066;&quot;&gt;alert&lt;/span&gt; = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color:rgb(255,234,216);&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #C00000;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; i &lt;span style=&quot;color: #C00000;&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color: #C00000;&quot;&gt;this&lt;/span&gt; &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #000066;&quot;&gt;alert&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#40;&lt;/span&gt; a&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#91;&lt;/span&gt;i&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;br /&gt;
&lt;div style=&quot;background-color:rgb(255,234,216);&quot;&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
a.&lt;span style=&quot;color: #000066;&quot;&gt;alert&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This alerts the source code for the &lt;code&gt;alert&lt;/code&gt; method as well as the three letters in the array, because they are all properties of the underlying &lt;code&gt;Object&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The same thing happens if the &lt;code&gt;alert&lt;/code&gt; method is added via &lt;code&gt;Array.prototype&lt;/code&gt;:&lt;/p&gt;

&lt;div style=&quot;padding: 5px !important; border: 1px solid rgb(253,187,134) !important; background-color: rgb(255,253,245) !important; font-family: Verdana,sans-serif !important;&quot;&gt;&lt;div style=&quot;background-color: rgb(255,250,238) !important;&quot;&gt;&lt;div class=&quot;geshi-javascript&quot;&gt;&lt;div style=&quot;background-color:rgb(255,234,216);&quot;&gt;&lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; a = &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;a&#039;&lt;/span&gt;, &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;b&#039;&lt;/span&gt;, &lt;span style=&quot;color: #3366CC;&quot;&gt;&#039;c&#039;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;&lt;/div&gt;
Array.&lt;span style=&quot;color: #006600;&quot;&gt;prototype&lt;/span&gt;.&lt;span style=&quot;color: #000066;&quot;&gt;alert&lt;/span&gt; = &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color:rgb(255,234,216);&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #C00000;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #003366; font-weight: bold;&quot;&gt;var&lt;/span&gt; i &lt;span style=&quot;color: #C00000;&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color: #C00000;&quot;&gt;this&lt;/span&gt; &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #000066;&quot;&gt;alert&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#40;&lt;/span&gt; a&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#91;&lt;/span&gt;i&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;br /&gt;
&lt;div style=&quot;background-color:rgb(255,234,216);&quot;&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
a.&lt;span style=&quot;color: #000066;&quot;&gt;alert&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;color: #0000FF;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And that&amp;#8217;s where we get into trouble with &lt;a href=&quot;https://prototype.conio.net/&quot;&gt;Prototype&lt;/a&gt;, because it adds methods to &lt;code&gt;Array.prototype&lt;/code&gt;. This breaks any code that uses &lt;code&gt;for-in&lt;/code&gt; on an &lt;code&gt;Array&lt;/code&gt;. But as we just discussed, no one should do that, so it won&amp;#8217;t be a problem in any properly-written code. Right? Case closed.&lt;/p&gt;

&lt;p&gt;Rob &lt;a href=&quot;https://ajaxian.com/archives/javascript-associative-arrays-considered-harmful&quot;&gt;puts it more strongly&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The other problem with using Arrays as associative arrays means you can no longer extend &lt;code&gt;Array.prototype&lt;/code&gt;, which is what Prototype 1.5 does to &lt;a href=&quot;https://encytemedia.com/blog/articles/2005/12/07/prototype-meets-ruby-a-look-at-enumerable-array-and-hash&quot;&gt;great effect&lt;/a&gt;. Prototype &lt;strong&gt;did&lt;/strong&gt; break Object associative arrays in 1.4 with additions to Object.prototype, something that is fixed in 1.5 after much &lt;a href=&quot;https://erik.eae.net/archives/2005/06/06/22.13.54/&quot;&gt;wailing and gnashing of teeth&lt;/a&gt;. Some might argue extending any of the built-in objects&amp;#8217; prototypes is bad form, but those people are wrong.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I wouldn&amp;#8217;t argue that it&amp;#8217;s bad form, but extending the native object prototypes causes real pain for two groups of people:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;People who write JavaScript widgets to be used on other websites, and&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;People who use third-party JavaScript widgets on their sites.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It&amp;#8217;s that whole Web 2.0 mashup thing, you know?&lt;/p&gt;

&lt;p&gt;As a widget author, if I use Prototype, then sooner or later one of my customers will want to combine my widgets with JavaScript code from somebody who &lt;em&gt;does&lt;/em&gt; use a &lt;code&gt;for-in&lt;/code&gt; loop on an array&amp;#8212;&amp;#8220;correct&amp;#8221; or not. Or code that uses some other library that &lt;em&gt;also&lt;/em&gt; extends &lt;code&gt;Array.prototype&lt;/code&gt;&amp;#8212;even a different version of Prototype that conflicts with mine.&lt;/p&gt;

&lt;p&gt;I love the good taste of syntactic sugar as much as anyone, and if it didn&amp;#8217;t break other code I&amp;#8217;d be merrily adding methods to the native objects too. But I have to make my code compatible not only with the code I control, but the code I don&amp;#8217;t. So it&amp;#8217;s no Prototype for me.&lt;/p&gt;
</description>
 <comments>https://mg.to/2006/05/20/prototype-vs-web-2-0#comments</comments>
 <category domain="https://mg.to/topics/programming/javascript">JavaScript</category>
 <pubDate>Sat, 20 May 2006 16:21:19 +0000</pubDate>
 <dc:creator>Michael Geary</dc:creator>
 <guid isPermaLink="false">163 at https://mg.to</guid>
</item>
</channel>
</rss>
