<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Perfection kills</title>
	
	<link>http://perfectionkills.com</link>
	<description>Exploring Javascript by example</description>
	<lastBuildDate>Wed, 06 Mar 2013 08:36:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/PerfectionKills" /><feedburner:info uri="perfectionkills" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Profiling CSS for fun and profit. Optimization notes.</title>
		<link>http://feedproxy.google.com/~r/PerfectionKills/~3/Oy81c8npp2c/</link>
		<comments>http://perfectionkills.com/profiling-css-for-fun-and-profit-optimization-notes/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 19:03:29 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[benchmark]]></category>
		<category><![CDATA[css]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=498</guid>
		<description><![CDATA[.profiling-css ul li { margin-bottom: 5px; } I&#8217;ve been recently working on optimizing performance of a so-called one-page web app. The application was highly dynamic, interactive, and was heavily stuffed with new CSS3 goodness. I&#8217;m not talking just border-radius and gradients. It was a full stack of shadows, gradients, transforms, sprinkled with transitions, smooth half-transparent [...]]]></description>
			<content:encoded><![CDATA[<div class="profiling-css">
<style>
  .profiling-css ul li {
    margin-bottom: 5px;
  }
</style>
<p>I&#8217;ve been recently working on optimizing performance of a so-called one-page web app. The application was highly dynamic, interactive, and was heavily stuffed with new CSS3 goodness. I&#8217;m not talking just border-radius and gradients. It was a full stack of shadows, gradients, transforms, sprinkled with transitions, smooth half-transparent colors, clever pseudo-element -based CSS tricks, and experimental CSS features.</p>
<p>Aside from looking into bottlenecks on Javascript/DOM side, I decided to step into the CSS land. I wanted to see the kind of impact these nice UI elements have on performance. The old version of the app — the one without all the fluff — was much snappier, even though the JS logic behind it hasn&#8217;t changed all that drastically. I could see by scrolling and animations that things are just not as quick as they should be.</p>
<p>Was styling to blame?</p>
<p>Fortunately, just few days before, Opera folks <a href="http://my.opera.com/dragonfly/blog/style-profiler-preview">came out with an experimental &#8220;style profiler&#8221;</a> (followed by WebKit&#8217;s ticket+patch <a href="https://bugs.webkit.org/show_bug.cgi?id=74004">shortly after</a>). The profiler was meant to reveal the performance of CSS selector matching, document reflow, repaint, and even document and css parsing times.</p>
<p>Perfect!</p>
<p><img src="http://files.myopera.com/hzr/files/profiler.png" width="900px"></p>
<p>I wasn&#8217;t thrilled about profiling in one environment, and optimizing according to one engine (especially the engine that&#8217;s used only in one browser), but decided to give it a try. After all, the offending styles/rules would probably be similar in all engines/browsers. And this was pretty much the only thing out there. </p>
<p>The only other somewhat similar tool was WebKit&#8217;s &#8220;timeline&#8221; tab in Developer Tools. But timeline wasn&#8217;t very friendly to work with. It wouldn&#8217;t show total time of reflow/repaint/selector matching, and the only way to extract that information was by exporting data as json and parsing it manually (I&#8217;ll get to that later).</p>
<p>Below are some of my observations from profiling using both WebKit and Opera tools. <a href="#summary">TL;DR version is at the end.</a></p>
<div style="background:#ffe;padding:5px;box-shadow:rgba(0,0,0,0.2) 0 0 3px">
<p>Before we start, I&#8217;d like to mention that most (if not all) of these notes apply best to large, complex applications. Documents that have thousands of elements and that are highly interactive will benefit the most. In my case, I reduced page load time by ~650ms (~500ms (!) on style recalculation alone, ~100ms on repaint, and ~50ms on reflow). The application became noticeably snappier, especially in older browsers like IE7.</p>
<p>For simpler pages/apps, there are plenty of other optimizations that should be looked into first.</p>
</div>
<h2 id="notes">Notes</h2>
<ol>
<li>
<p>The fastest rule is the one that doesn&#8217;t exist. There&#8217;s a common strategy to combine stylesheet &#8220;modules&#8221; into one file for production. This makes for one big collection of rules, where some (lots) of them are likely not used by particular part of the site/application. <strong>Getting rid of unused rules</strong> is one of the best things your can do to optimize CSS performance, as there&#8217;s less matching to be done in the first place. There are certain benefits of having one big file, of course, such as the reduced number of requests. But it should be possible to optimize at least critical parts of the app, by including only relevant styles. </p>
<p>This isn&#8217;t a new discovery by any means. Page Speed <a href="http://code.google.com/speed/page-speed/docs/payload.html#RemoveUnusedCSS">has always been warning against this</a>. However, I was really surprised to see <strong>just how much</strong> this could really affect the rendering time. In my case, I shaved ~200-300ms of selector matching — according to Opera profiler — just by getting rid of unused CSS rules. Layout and paint times went down as well.</p>
</li>
<li>
<p>Reducing reflows — another well-known optimization — plays big role here as well. Expensive styles are not so expensive when fewer reflows/repaints need to be performed by the browser. And even simple styles could slow things down if they&#8217;re applied a lot. Reducing reflows AND reducing complexity of CSS go hand in hand.</p>
</li>
<li>
<p>Most expensive selectors tend to be universal ones (<code>"*"</code>), and those with multiple classes (<code>".foo.bar"</code>, <code>"foo .bar.baz qux"</code>, etc.). We already knew this, but it&#8217;s nice to get confirmation from profilers.</p>
</li>
<li>
<p>Watch out for universal selectors (<code>"*"</code>) that are used for &#8220;no reason&#8221;. I found selectors like <code>"button &gt; *"</code>, even though throughout the site/app buttons only had <code>&lt;span&gt;</code>&#8217;s in them. Replacing <code>"button &gt; *"</code> with <code>"button &gt; span"</code> made for some amazing improvements in selector performance. The browser no longer needs to <strong>match every element</strong> (due to <a href="https://developer.mozilla.org/en/Writing_Efficient_CSS#How_the_Style_System_Matches_Rules">right-left matching</a>). It only needs to walk over &lt;span>&#8217;s — the number of which could be significantly smaller — and check if parent element is &lt;button>. You obviously need to be careful substituting <code>"*"</code> with specific tags, as it&#8217;s often hard to find all the places where this selector could be used. </p>
<p>The big downside of this optimization is that you <strong>lose flexibility</strong>, as changing markup will now require changing CSS as well. You won&#8217;t be able to just replace one button implementation with another one in the future. I felt iffy doing this replacement, as it&#8217;s essentially getting rid of useful abstraction for the sake of performance. As always, find the right compromise for your particular case, until engines start to optimize such selectors and we don&#8217;t have to worry about them.</p>
</li>
<li>
<p>I used this snippet to quickly find which elements to substitute <code>"*"</code> with.</p>
<pre lang="javascript"><code>
$$(selector).pluck('tagName').uniq(); // ["SPAN"]</code></pre>
<p>This relies on <a href="http://www.prototypejs.org/api/enumerable/pluck"><code>Array#pluck</code></a> and <a href="http://prototypejs.org/api/array/uniq"><code>Array#uniq</code></a> extensions from Prototype.js. For plain version (with reliance on ES5 and selectors API), perhaps something like this would do:</p>
<pre lang="javascript"><code>
Object.keys([].slice.call(
  document.querySelectorAll('button &gt; *'))
    .reduce(function(memo, el){ memo[el.tagName] = 1; return memo; }, {}));
</code></pre>
</li>
<li>
<p>In both Opera and WebKit, <code>[type="..."]</code> selectors seem to be more expensive than <code>input[type="..."]</code>. Probably due to browsers limiting attribute check to elements of specified tag (after all, <code>[type="..."]</code> IS a universal selector).</p>
</li>
<li>
<p>In Opera, pseudo <code>"::selection"</code> and <code>":active"</code> are also among more expensive selectors — according to profiler. I can understand <code>":active"</code> being expensive, but not sure why <code>"::selection"</code> is. Perhaps a &#8220;bug&#8221; in Opera&#8217;s profiler/matcher. Or just the way engine works.</p>
</li>
<li>
<p>In both Opera and WebKit, <code>"border-radius"</code> is <strong>among the most expensive CSS properties</strong> to affect rendering time. Even more than shadows and gradients. Note that it doesn&#8217;t affect <strong>layout</strong> time — as one would think — but mainly <strong>repaint</strong>.</p>
<p>As you can see from <a href="https://github.com/kangax/perfectionkills.com/blob/master/css_perf/css_perf_test.html">this test page</a>, I created a document with 400 buttons.</p>
<p><img src="https://github.com/kangax/perfectionkills.com/raw/master/css_perf/buttons.png" alt="Buttons" title="" /></p>
<p>I started checking how various styles affect rendering performance (&#8220;repaint time&#8221; in profiler). The basic version of button only had these styles:</p>
<pre lang="css"><code>
background: #F6F6F6;
border: 1px solid rgba(0, 0, 0, 0.3);
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 14px;
height: 32px;
vertical-align: middle;
padding: 7px 10px;
float: left;
margin: 5px;
</code></pre>
<p><img src="https://github.com/kangax/perfectionkills.com/raw/master/css_perf/btn_before.png" alt="Btn Before" title="" /></p>
<p>The total repaint time of 400 buttons with these basic styles only took 6ms (in Opera). I then gradually added more styles, and recorded change in repaint time. The final version had these additional styles, and was taking 177ms to repaint — a 30x increase!</p>
<pre lang="css"><code>
text-shadow: rgba(255, 255, 255, 0.796875) 0px 1px 0px;
box-shadow: rgb(255, 255, 255) 0px 1px 1px 0px inset, rgba(0, 0, 0, 0.0976563) 0px 2px 3px 0px;
border-radius: 13px;
background: -o-linear-gradient(bottom, #E0E0E0 50%, #FAFAFA 100%);
opacity: 0.9;
color: rgba(0,0,0,0.5);
</code></pre>
<p><img src="https://github.com/kangax/perfectionkills.com/raw/master/css_perf/btn_after.png" alt="Btn After" title="" /></p>
<p>The exact breakdown of each one of those properties was as follows:</p>
<p><script type="text/javascript" src="//ajax.googleapis.com/ajax/static/modules/gviz/1.0/chart.js"> {"dataSourceUrl":"//docs.google.com/spreadsheet/tq?key=0Aqj_mVmuz3Y8dEg0S2pmOW0xbll3OUhkcFN6TFJaaVE&#038;transpose=0&#038;headers=0&#038;range=A2%3AB9&#038;gid=0&#038;pub=1","options":{"height":371,"width":600,"hAxis":{"viewWindowMode":"pretty","viewWindow":{}},"hasLabelsColumn":true,"isStacked":false},"state":{},"view":"{\"columns\":[0,1]}","chartType":"BarChart","chartName":"Chart 1"} </script></p>
<p>The text-shadow and linear-gradient were among the least expensive ones. Opacity and transparent rgba() color were a little more expensive. Then there was box-shadow, with inset one (<code>0 1px 1px 0</code>) slightly faster than regular one (<code>0 2px 3px 0</code>). Finally, the unexpectedly high border-radius.</p>
<p>I also tried transform with rotate parameter (just 1deg) and got really high numbers. Scrolling the page — with 400 slightly rotated buttons on it — was also noticeably jerky. I&#8217;m sure it&#8217;s not easy to arbitrarily transform an element on a page. Or maybe this is the case of lack of optimization? Out of curiosity, I checked different degrees of rotation and got this:</p>
<p><script type="text/javascript" src="//ajax.googleapis.com/ajax/static/modules/gviz/1.0/chart.js"> {"dataSourceUrl":"//docs.google.com/spreadsheet/tq?key=0Aqj_mVmuz3Y8dGN2M21jWjR1akpnQVE0OFJrLXlhOVE&#038;transpose=0&#038;headers=0&#038;range=A2%3AB7&#038;gid=0&#038;pub=1","options":{"hAxis":{"viewWindowMode":"pretty","viewWindow":{}},"hasLabelsColumn":true,"isStacked":false,"width":600,"height":371},"state":{},"view":"{\"columns\":[0,1]}","chartType":"BarChart","chartName":"Chart 1"} </script></p>
<p>Note how even rotating element by 0.01 degree is very expensive. And as the angle increases, the performance seems to drop, although not linearly but apparently in a wavy fashion (peaking at 45deg, then falling at 90deg).</p>
<p>There&#8217;s room for so many tests here — I&#8217;d be curious to see performance characteristics of various transform options (translate, scale, skew, etc.) in various browsers.</p>
</li>
<li>
<p>In Opera, <strong>page zoom level affects layout performance</strong>. Decreasing zoom increases rendering time. This is quite understandable, as more stuff has to be rendered per same area. It might seem like an insignificant detail, but in order to keep tests consistent, it&#8217;s important to make sure zoom level doesn&#8217;t mess up your calculations. I had to redo all my tests after discovering this, just to make sure I&#8217;m not comparing oranges to grapefruits.</p>
<p>Speaking of zoom, it could make sense to test decreased font and see how it affects overall performance of an app — is it still usable?</p>
</li>
<li>
<p>In Opera, resizing browser window <strong>doesn&#8217;t affect rendering performance</strong>. It looks like layout/paint/style calculations are not affected by window size.</p>
</li>
<li>
<p>In Chrome, resizing browser window <strong>does affect performance</strong>. Perhaps Chrome is smarter than Opera, and only renders visible areas.</p>
</li>
<li>
<p>In Opera, <strong>page reloads negatively affect performance</strong>. The progression is visibly linear. You can see from the graph how rendering time slowly increases over 40 page reloads (each one of those red rectangles on the bottom correspond to page load followed by few second wait). Paint time becomes almost 3 times slower at the end. It looks almost like page is leaking. To err on a side of caution, I always used the average of first ~5 results to get &#8220;fresh&#8221; numbers.</p>
<p><img src="https://github.com/kangax/perfectionkills.com/raw/master/css_perf/profiler_page_reload.png" alt="Profiler Page Reload" style="width:900px"></p>
<p>Script used for testing (reloading page):</p>
<pre lang="javascript"><code>
window.onload = function() {
  setTimeout(function() {
    var match = location.href.match(/\?(\d+)$/);
    var index = match ? parseInt(match[1]) : 0;
    var numReloads = 10;
    index++;
    if (index &lt; numReloads) {
      location.href = location.href.replace(/\?\d+$/, '') + '?' + index;
    }
  }, 5000);
};
</code></pre>
<p>I haven&#8217;t checked if page reloads affect performance in WebKit/Chrome.</p>
</li>
<li>
<p>An interesting offending pattern I came across was a <a href="http://sass-lang.com/">SASS</a> chunk like this:</p>
<pre lang="css"><code>
a.remove &gt; * {
  /* some styles */
  .ie7 &amp; {
    margin-right: 0.25em;
  }
}
</code></pre>
<p>..which would generate CSS like this:</p>
<pre lang="css"><code>
a.remove &gt; * { /* some styles */ }
.ie7 a.remove &gt; * { margin-right: 0.25em }
</code></pre>
<p>Notice the additional IE7 selector, and how it has a universal rule. We know that universal rules are slow due to right-left matching, and so all browsers except IE7 (which .ie7 — probably on &lt;body> element — is supposed to target) are taking an unnecessary performance hit. This is obviously the worst case of IE7-targeted selector.</p>
<p>Other ones were more innocent:</p>
<pre lang="css"><code>
.steps {
  li {
    /* some styles */
    .ie7 &amp; {
      zoom: 1;
    }
  }
}
</code></pre>
<p>..which produces CSS like:</p>
<pre lang="css"><code>
.steps li { /* some styles */ }
.ie7 .steps li { zoom: 1 }
</code></pre>
<p>But even in this case engine needs to check each <code>&lt;li&gt;</code> element (that&#8217;s within element with class &#8220;steps&#8221;) until it would &#8220;realize&#8221; that there&#8217;s no element with &#8220;ie7&#8221; class further up the tree.</p>
<p>In my case, there was close to a hundred of such .ie7 and .ie8 -based selectors in a final stylesheet. Some of them were universal. The fix was simple — move all IE-related styles to a separate stylesheet, included via conditional comments. As a result, there were that many less selectors to parse, match and apply.</p>
<p>Unfortunately, this kind of optimization <strong>comes with a price</strong>. I find that putting IE-related styles next to the original ones is actually a more maintainable solution. When changing/adding/removing something in the future, there&#8217;s only one place to change and so there&#8217;s less chance to forget IE-related fixes. Perhaps in the future tools like SASS could optimize declarations like these out of the main file and into conditionally-included ones.</p>
</li>
<li>
<p>In Chrome (and WebKit), you can use &#8220;Timeline&#8221; tab in Developer tools to get similar information about repaint/reflow/style recalculation performance. Timeline tab allows you to export data as JSON. First time I&#8217;ve seen this done was by <a href="http://calendar.perfplanet.com/2011/pure-css3-images-hmm-maybe-later/">Marcel Duran</a> in this year&#8217;s <a href="http://calendar.perfplanet.com/2011">Performance Calendar</a>. Marcel used node.js and a <a href="https://github.com/marcelduran/sandbox.javascriptrules.com/blob/gh-pages/purecss3image/rendering/summary.js">script</a> to parse and extract data.</p>
<p>Unfortunately, his script was including &#8220;Recalculate styles&#8221; time in the &#8220;layout&#8221; time — something I wanted to avoid. I also wanted to avoid page reloads (and getting average/median time). So I tweaked it to a much simpler version. It walks over entire data, filtering entries related to Repaint, Layout, and Style Calculation; then sums up total time for each of those entries:</p>
<pre lang="javascript"><code>
var LOGS = './logs/',
    fs = require('fs'),
    files =  fs.readdirSync(LOGS);

files.forEach(function (file, index) {
  var content = fs.readFileSync(LOGS + file),
      log,
      times = {
        Layout: 0,
        RecalculateStyles: 0,
        Paint: 0
      };

  try {
    log = JSON.parse(content);
  }
  catch(err) {
    console.log('Error parsing', file, ' ', err.message);
  }
  if (!log || !log.length) return;

  log.forEach(function (item) {
    if (item.type in times) {
      times[item.type] += item.endTime - item.startTime;
    }
  });

  console.log('\nStats for', file);
  console.log('\n  Layout\t\t', times.Layout.toFixed(2), 'ms');
  console.log('  Recalculate Styles\t', times.RecalculateStyles.toFixed(2), 'ms');
  console.log('  Paint\t\t\t', times.Paint.toFixed(2), 'ms\n');
  console.log('  Total\t\t\t', (times.Layout + times.RecalculateStyles + times.Paint).toFixed(2), 'ms\n');
});
</code></pre>
<p>After saving timeline data and running a script, you would get information like this:</p>
<pre lang="javascript"><code>
Layout                      6.64 ms
Recalculate Styles          0.00 ms
Paint                       114.69 ms

Total                       121.33 ms
</code></pre>
<p>Using Chrome&#8217;s &#8220;Timeline&#8221; and this script, I ran original button test that I tested before in Opera and got this:</p>
<p><script type="text/javascript" src="//ajax.googleapis.com/ajax/static/modules/gviz/1.0/chart.js"> {"dataSourceUrl":"//docs.google.com/spreadsheet/tq?key=0Aqj_mVmuz3Y8dHNncTEtTHRUZGlVazNaUmxHdWJhRXc&#038;transpose=0&#038;headers=0&#038;range=A2%3AB7&#038;gid=0&#038;pub=1","options":{"hAxis":{"viewWindowMode":"pretty","viewWindow":{}},"hasLabelsColumn":true,"isStacked":false,"width":600,"height":371},"state":{},"view":"{\"columns\":[0,1]}","chartType":"BarChart","chartName":"Chart 1"} </script></p>
<p>Similarly to Opera, border-radius was among least performant. However, linear-gradient was comparatively more expensive than that in Opera and box-shadow was much higher than text-shadow.</p>
<p>One thing to note about Timeline is that it only provides &#8220;Layout&#8221; information, whereas Opera&#8217;s profiler has &#8220;Reflow&#8221; AND &#8220;Layout&#8221;. I&#8217;m not sure if reflow data analogous to Opera&#8217;s is included in WebKit&#8217;s &#8220;Layout&#8221; or if it&#8217;s discarded. Something to find out in the future, in order to have correct testing results.</p>
</li>
<li>
<p>When I was almost done with my findings, WebKit has added selector profiler similar to Opera&#8217;s one.</p>
<p><img src="https://bug-74004-attachments.webkit.org/attachment.cgi?id=118220" width="900"></p>
<p>I wasn&#8217;t able to do many tests with it, but noticed one interesting thing. Selector matching in WebKit was <strong>marginally faster</strong> than that of Opera. The same document — that one-page app I was working on (before optimizations) — took 1,144ms on selector matching in Opera, and only 18ms in WebKit. That&#8217;s a ~65x difference. Either something is off in calculations of one of the engines, or WebKit is really much much faster at selector matching. For what it&#8217;s worth, Chrome&#8217;s timeline was showing ~37ms for total style recalculation (much closer to WebKit), and ~52ms for repaint (compare to Opera&#8217;s 225ms &#8220;Paint&#8221; total; different but much closer). I wasn&#8217;t able to save &#8220;Timeline&#8221; data in WebKit, so couldn&#8217;t check reflow and repaint numbers there.</p>
</li>
</ol>
<h3 id="summary">Summary</h3>
<ul>
<li>Reduce total number of selectors (including IE-related styles: <code>.ie7 .foo .bar</code>)</li>
<li>Avoid universal selectors (including unqualified attribute selectors: <code>[type="url"]</code>)</li>
<li>Page zoom affects CSS performance in some browsers (e.g. Opera)</li>
<li>Window size affects CSS performance in some browsers (e.g. Chrome)</li>
<li>Page reloads can negatively affect CSS performance in some browsers (e.g. Opera)</li>
<li>&#8220;border-radius&#8221; and &#8220;transform&#8221; are among most expensive properties (in at least WebKit &amp; Opera)</li>
<li>&#8220;Timeline&#8221; tab in WebKit-based browsers can shed light on total recalc/reflow/repaint times</li>
<li>Selector matching is much faster in WebKit</li>
</ul>
<h3 id="questions">Questions</h3>
<p>As I end these notes, I have tons of other questions related to CSS performance:</p>
<ul>
<li>Quoted attribute values vs. unquoted ones (e.g. <code>[type=search]</code> vs <code>[type="search"]</code>). How does this affect performance of selector matching?</li>
<li>What are the performance characteristics of <strong>multiple</strong> box-shadows/text-shadows/backgrounds? 1 text-shadow vs. 3 vs. 5.</li>
<li>Performance of pseudo selectors (:before, :after).</li>
<li>How do different border-radius values affect performance? Is higher radius more expensive? Does it grow linearly?</li>
<li>Does !important declaration influence performance? How?</li>
<li>Does hardware acceleration influence performance? How?</li>
<li>Are styles similarly expensive in different combinations? (e.g. text-shadow with linear-gradient vs. text-shadow on one-color background)</li>
</ul>
<h3 id="future">Future</h3>
<p>As our pages/apps become more interactive, the complexity of CSS increases, and browsers start to support more and more &#8220;advanced&#8221; CSS features, CSS performance will probably become even more important. The existing tools are only scratching the surface. We need the ones for mobile testing and tools in more browsers (IE, Firefox). I <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=713031">created a ticket for Mozilla</a>, so perhaps we&#8217;ll see something come out of it soon. I would love to see CSS performance data exposed via scripting, so that we could utilize it in tools like <a href="http://jsperf.com">jsperf.com</a> (<a href="http://cssperf.com">cssperf.com</a>?). Meanwhile, there&#8217;s plenty of tests to be done with existing profilers. So what are you waiting for? ;)</p>
</div>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerfectionKills?a=Oy81c8npp2c:B_H-De38p1k:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerfectionKills?i=Oy81c8npp2c:B_H-De38p1k:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerfectionKills/~4/Oy81c8npp2c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/profiling-css-for-fun-and-profit-optimization-notes/feed/</wfw:commentRss>
		<slash:comments>73</slash:comments>
		<feedburner:origLink>http://perfectionkills.com/profiling-css-for-fun-and-profit-optimization-notes/</feedburner:origLink></item>
		<item>
		<title>Fabric.js 0.5 is out</title>
		<link>http://feedproxy.google.com/~r/PerfectionKills/~3/E4KKj5QN24M/</link>
		<comments>http://perfectionkills.com/fabric-js-0-5-is-out/#comments</comments>
		<pubDate>Mon, 22 Aug 2011 17:31:15 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=451</guid>
		<description><![CDATA[Remember that fabulous canvas library that makes working with canvas a breeze? The one that can parse SVG files on the fly and fluently draw them on canvas; that can render complex text in real time; that can morph objects with a touch of a mouse; with sophisticated, programmatically-accessible object model; easy to use animation [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://github.com/kangax/fabric.js/raw/master/lib/screenshot.png" style="box-shadow:rgba(0,0,0,0.3) 0 0 5px"></p>
<p>Remember that <a href="http://kangax.github.com/fabric.js/demos/kitchensink/">fabulous canvas library</a> that makes working with canvas a breeze? The one that can <a href="http://www.slideshare.net/kangax/fabric-falsy-values-8067834/28">parse SVG files</a> on the fly and fluently draw them on canvas; that can render <a href="http://www.slideshare.net/kangax/fabric-falsy-values-8067834/22">complex text</a> in real time; that can morph objects with a touch of a mouse; with sophisticated, programmatically-accessible <a href="http://www.slideshare.net/kangax/fabricjs-building-acanvaslibrarybk/18">object model</a>; <a href="http://kangax.github.com/fabric.js/demos/ladybug/">easy to use animation</a> and <a href="http://kangax.github.com/fabric.js/demos/events/">event infrastructure</a>?</p>
<p>Why yes, of course I&#8217;m talking about <a href="https://github.com/kangax/fabric.js">Fabric.js</a> ;)</p>
<p>Version 0.5 is out and here&#8217;s a quick overview of 3 main changes:</p>
<h3 id="nodejs_npm_support">Node.js &amp; NPM support</h3>
<p>Fabric can now run on a server, under <a href="http://nodejs.org/">Node.js</a>, thanks to wonderful <a href="https://github.com/tmpvar/jsdom">jsdom</a> and <a href="http://blog.learnboost.com/blog/introducing-node-canvas-server-side-html5-canvas-api/">node-canvas</a> libraries. It&#8217;s basically a wrapper on top of <b>node-canvas</b> that&#8217;s on top of <b>jsdom</b> that&#8217;s on top of <b>node</b>.</p>
<p>Fabric is also registered as <a href="http://search.npmjs.org/#/fabric">NPM package</a>, so can be installed with the usual one-liner:</p>
<pre lang="javascript"><code>
> npm install fabric</code></pre>
<p>Here&#8217;s how you would use it:</p>
<pre lang="javascript"><code>
var fabric = require('fabric').fabric,
    canvas = fabric.createCanvasForNode(200, 200);

canvas.add(new fabric.Rect({
  top: 100,
  left: 100,
  width: 100,
  height: 50,
  angle: 30,
  fill: 'rgba(255,0,0,0.5)'
}));

var out = require('fs').createWriteStream(__dirname + '/rectangle.png'),
    stream = canvas.createPNGStream();

stream.on('data', function(chunk) {
  out.write(chunk);
});
</code></pre>
<p>.. and here&#8217;s what the resulting image would be — 30&deg; rotated half-transparent, red rectangle.</p>
<p><img src="http://dl.dropbox.com/u/822184/rect.png" style="box-shadow:rgba(0,0,0,0.3) 0 0 5px"></p>
<p>I&#8217;m really excited about Node support in fabric. We&#8217;ll be using it in production on <a href="http://printio.ru">Printio.ru</a> shortly.</p>
<h3 id="custom_builder">Custom builder</h3>
<p>It&#8217;s now possible to create custom fabric build, including only those modules that you need. The build process was rewritten to use Node.js instead of <a href="http://getsprockets.org/">Sprockets</a>. Building can only be done via command line for now. Online interface is likely to come in the future:</p>
<pre lang="javascript"><code>
> node build.js modules=xxx,yyy,zzz
</code></pre>
<p>.. where &#8220;xxx&#8221;, &#8220;yyy&#8221;, and &#8220;zzz&#8221; are the names of the modules. Currently available modules are &#8220;text&#8221;, &#8220;serialization&#8221;, &#8220;parser&#8221;, and &#8220;node&#8221;. By default none of these modules are included. If you wish to include all of the modules, you can use &#8220;ALL&#8221; keyword:</p>
<pre lang="javascript"><code>
> node build.js modules=ALL
</code></pre>
<h3 id="smaller_footprint">Smaller footprint</h3>
<p>By moving some of the functionality into optional modules (e.g. &#8220;parser&#8221; and &#8220;serialization&#8221;), default minimalistic version of fabric is now ~76KB (~22KB gzipped). There&#8217;s still more reduction that can be done, so expect even smaller footprint in the near future.</p>
<p>Enjoy.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerfectionKills?a=E4KKj5QN24M:qNJa4O3c-Oo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerfectionKills?i=E4KKj5QN24M:qNJa4O3c-Oo:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerfectionKills/~4/E4KKj5QN24M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/fabric-js-0-5-is-out/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://perfectionkills.com/fabric-js-0-5-is-out/</feedburner:origLink></item>
		<item>
		<title>Extending built-in native objects. Evil or not?</title>
		<link>http://feedproxy.google.com/~r/PerfectionKills/~3/KY_urCReX7U/</link>
		<comments>http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 18:56:22 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[ECMA-262]]></category>
		<category><![CDATA[ES5]]></category>
		<category><![CDATA[[[Prototype]]]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=438</guid>
		<description><![CDATA[Few days ago, Nick Morgan asked my opinion on extending native objects. The question came up when trying to answer — &#8220;why doesn&#8217;t underscore.js extend built-ins&#8221;? Why doesn&#8217;t it define all those Array methods — like map, forEach, every — on Array.prototype. Why does it put them under _ &#8220;namespace&#8221; — _.each, _.map, _.every, etc. [...]]]></description>
			<content:encoded><![CDATA[<p>Few days ago, Nick Morgan <a href="https://twitter.com/#!/skilldrick/status/96950919014518785">asked my opinion</a> on extending native objects. The <a href="http://www.reddit.com/r/programming/comments/j32gc/easy_functional_programming_in_javascript_with/c28qyxm">question came up</a> when trying to answer — &#8220;why doesn&#8217;t <a href="http://documentcloud.github.com/underscore">underscore.js</a> extend built-ins&#8221;? Why doesn&#8217;t it define all those Array methods — like <code>map</code>, <code>forEach</code>, <code>every</code> — on <code>Array.prototype</code>. Why does it put them under <code>_</code> &#8220;namespace&#8221; — <code>_.each</code>, <code>_.map</code>, <code>_.every</code>, etc. Is it because extending built-in natives is evil? Or is it not? The thread quickly filled with conflicting ideas&#8230;</p>
<p>I often see this confusion about extending things in Javascript.</p>
<p>There&#8217;s a <strong>big difference</strong> between extending <strong>native</strong> built-in objects and extending <strong>host</strong> objects. I tried to explain what&#8217;s wrong with extending host objects <a href="http://perfectionkills.com/whats-wrong-with-extending-the-dom/">in a blog post, a while back</a>. Now, if you look at the list of problems with extending host objects it&#8217;s easy to see that most of them don&#8217;t really apply to native, built-in objects.</p>
<p>To avoid any confusion, by native, built-in objects I&#8217;m talking about objects and methods introduced in ES5 — <code>Array.prototype</code> extensions (<code>forEach</code>, <code>map</code>, <code>reduce</code>, etc.), <code>Object</code> extensions (<code>Object.create</code>, <code>Object.keys</code>, etc.), <code>Function.prototype.bind</code>, <code>String.prototype.trim</code>, <code>JSON.*</code>, etc. These are the things that are shimmed most often. And the question is — is it OK to extend native, built-in objects with these standardized methods?</p>
<p>Well, let&#8217;s quickly go over problems with host objects extension:</p>
<h3 id="host_vs_native">Host vs. Native</h3>
<ul>
<li>
<p><a href="http://perfectionkills.com/whats-wrong-with-extending-the-dom/#lack_of_specification">&#8220;Lack of specification&#8221;</a> doesn&#8217;t apply here, as long as methods that are being shimmed are <strong>part of ES5 (or ES3)</strong>. ES5 is a standard. There&#8217;s a <a href="http://es5.github.com/">publicly available specification</a>. Implementing ES5 methods according to spec is doable (except certain <a href="https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js#L487-544">edge-ish cases</a>).</p>
</li>
<li>
<p><a href="http://perfectionkills.com/whats-wrong-with-extending-the-dom/#host_objects_have_no_rules">&#8220;Host objects have no rules&#8221;</a> doesn&#8217;t apply either. This is <strong>native</strong> objects we&#8217;re dealing with, and semantics of native objects are very well defined in those same ECMA-262 specifications. What this means in practice is that unless we&#8217;re dealing with faulty implementations, adding method <code>bind</code> to <code>Function.prototype</code> should allow us to add it. There&#8217;s no uncertainty about <code>Function.prototype</code> throwing error on extension, or silently ignoring our command (after all, the spec says: <a href="http://es5.github.com/#x15.3.4">&#8220;The initial value of the [[Extensible]] internal property of the Function prototype object is true&#8221;</a>). Ditto for other objects.</p>
</li>
<li>
<p><a href="http://perfectionkills.com/whats-wrong-with-extending-the-dom/#chance_of_collisions">&#8220;Chance of collisions&#8221;</a> is non-existent as well. Since the methods that are being shimmed are part of a standard, and we&#8217;re shimming them according to standard, there&#8217;s no chance of collisions of any sort. Either implementation has those methods, or it doesn&#8217;t. If it doesn&#8217;t, methods are shimmed. That&#8217;s it.</p>
</li>
<li>
<p><a href="http://perfectionkills.com/whats-wrong-with-extending-the-dom/#performance_overhead">&#8220;Performance overhead&#8221;</a> not only doesn&#8217;t exist, but could actually be the opposite of what happens. It&#8217;s likely that <code>[].forEach(...)</code> will be faster then <code>_.forEach([], ...)</code>, but even if it isn&#8217;t, there should certainly be no performance hit with former version. Contrary to DOM objects that might not have [[Prototype]]&#8217;s exposed for public extension, there&#8217;s no need to manually extend arrays, objects and strings with these methods. Conceptually, there&#8217;s no performance overhead there.</p>
</li>
<li>
<p><a href="http://perfectionkills.com/whats-wrong-with-extending-the-dom/#ie_dom_is_a_mess">&#8220;IE DOM is a mess&#8221;</a> doesn&#8217;t apply. We&#8217;re not dealing with DOM. And native objects are extension-friendly in IE, as far as I know.</p>
</li>
</ul>
<p>So what do we have?</p>
<p>Well, it looks like properly extending native objects — unlike <strong>host</strong> ones — is actually not all that bad. This is of course considering that we&#8217;re talking about <strong>standard objects and methods</strong>. Extending native built-ins with <strong>custom methods</strong> immediately makes &#8220;collision&#8221; problem apparent. It violates <a href="http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/">&#8220;don&#8217;t modify objects you don&#8217;t own&#8221; principle</a>, and makes code not future-proof.</p>
<h3 id="downsides">Downsides</h3>
<p>Are there any downsides?</p>
<p>Well, for once, there are cases when certain scripts mess up native objects/methods in a <strong>non-compliant way</strong>. Kind of like what Prototype.js does with some of its methods (e.g. <a href="https://github.com/sstephenson/prototype/blob/1fb9728/src/lang/enumerable.js#L250-257"><code>Array.prototype.map</code></a> or <a href="https://github.com/sstephenson/prototype/blob/1fb9728ed109cfd682225a13eda13acfb91a94dc/src/lang/array.js#L321-323"><code>Array.prototype.reverse</code></a>; standard-compliance is planned for future releases, as far as I know). If the shim adds standard-compliant methods, and application expects those methods to be non-compliant (but script/library-specific), then there could obviously be problems.</p>
<p>Second, as I mentioned above, while we know that native objects are free for extension, there&#8217;s always a risk of running into an oddball environment which doesn&#8217;t conform to spec. Keeping methods on a standalone (user-defined) object can avoid such scenarios. Whether this could be considered an issue depends on how paranoid you are.</p>
<p>Finally, you have to be careful when shimming methods that are not universally shimmable. Like <code>Object.create</code>, which had a very popular <a href="http://stackoverflow.com/questions/3075308/what-modernizer-scripts-exist-for-the-new-ecmascript-5-functions/3075818#3075818">non-compliant shim floating around</a> for a while. The method was defined directly on an <code>Object</code>, but silently failed to do anything useful with second argument — a set of property descriptors. Adding cross-browser support for property descriptors is a <a href="https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js#L487-544">rather complicated endeavor</a>, which is why defining such methods on a standalone object could save you some trouble (you could just implement a subset of <code>Object.create</code> functionality and call it a day).</p>
<p>Don&#8217;t forget that <a href="https://gist.github.com/1120592">writing proper, compliant shims is hard</a>. When in doubt, use standalone object. When the method you&#8217;re shimming is part of the unfinished spec, use standalone object. Only when you&#8217;re certain about method compliance and method is part of the finished, future-proof specification, is it safe to shim native object directly.</p>
<h3 id="enumerability">Enumerability</h3>
<p>Another interesting, but likely insignificant difference is enumerability of shimmed methods. Unless methods are added using ES5 additions that allow to specify property enumerability (<code>Object.defineProperty</code> or <code>Object.defineProperties</code>), methods end up being enumerable:</p>
<pre lang="javascript"><code>
if (!Array.prototype.map) {
  Array.prototype.map = function() { /* ... */ };
}
Object.keys(Array.prototype); // ["map"]

// can be worked around:

if (!Array.prototype.map) {
  Object.defineProperty(Array.prototype, 'map', {
    value: function() { /* ... */ }
  });
}
Object.keys(Array.prototype); // []
</code></pre>
<h3 id="underscorejs_and_api_consistency">Underscore.js and API consistency</h3>
<p>Getting back to underscore.js, I see an important aspect of <strong>consistency</strong>. Underscore adds not only standard methods like <code>map</code>, <code>reduce</code> and <code>trim</code>, but also its own, custom ones — <code>values</code>, <code>extend</code>, <code>clone</code>, etc. By adding <code>map</code>, <code>reduce</code>, and <code>trim</code> to standalone object, it keeps its API consistent.</p>
<p>I&#8217;d like to also mention that I do <a href="https://github.com/kangax/fabric.js/blob/gh-pages/src/util/lang_array.js#L18-49">extend <code>Array.prototype</code> in fabric.js</a> with methods like <code>forEach</code>, <code>map</code>, <code>every</code>. I make sure those methods are spec-compliant, and I take a risk of conflicts with libraries that shim methods in non-compliant way. Methods that are non-standard, on the other hand, are <a href="https://github.com/kangax/fabric.js/blob/gh-pages/src/util/lang_array.js#L179-183">defined under standalone utility object</a>. I&#8217;m not worried much about inconsistency, since — unlike in underscore.js — there&#8217;s only a handful of shimmed methods.</p>
<p>So there you have it. It should be now clear that extending native built-ins is definitely not as risky as messing with host objects. Do it carefully, follow spec closely, and use your reasonable judgement. For a spec-compliant shims, <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map#Compatibility">MDN is a good place to start with</a> (but don&#8217;t trust it blindly either, as there were cases of non-compliance there as well).</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerfectionKills?a=KY_urCReX7U:TCFZYg5rMas:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerfectionKills?i=KY_urCReX7U:TCFZYg5rMas:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerfectionKills/~4/KY_urCReX7U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/feed/</wfw:commentRss>
		<slash:comments>78</slash:comments>
		<feedburner:origLink>http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/</feedburner:origLink></item>
		<item>
		<title>Refactoring Javascript with kratko.js</title>
		<link>http://feedproxy.google.com/~r/PerfectionKills/~3/pPJxgB4qRKM/</link>
		<comments>http://perfectionkills.com/refactoring-javascript-with-kratko-js/#comments</comments>
		<pubDate>Mon, 13 Jun 2011 17:10:11 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=425</guid>
		<description><![CDATA[Understanding the concept of code refactoring is one of the best things you can do to become a better programmer [1]. It all started a couple of weeks ago when I — once again — looked at the growing, stinky mess that my code has become. It&#8217;s a few thousand LOC app with various interactive [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://dl.dropbox.com/u/822184/kratko_screenshot_1.png" style="width:700px"></p>
<p>Understanding the concept of <a href="http://en.wikipedia.org/wiki/Code_refactoring">code refactoring</a> is one of the best things you can do to become a better programmer <sup><a href="#on-refactoring">[1]</a></sup>.</p>
<p>It all started a couple of weeks ago when I — once again — looked at the growing, stinky mess that my code has become. It&#8217;s a few thousand <abbr title="Lines Of Code">LOC</abbr> app with various interactive widgets and controls all on one page. Even though a lot of functionality was encapsulated in these separately-defined widgets, the main &#8220;dashboard&#8221; object — a bootstrapper, so to speak — grew like a weed and became quite an abomination.</p>
<p>It was time for refactoring.</p>
<p>Every now and then I would clean things up. And so there I was, once again, trying to figure out where to start. One method was whopping 70 lines long. Another few of them — just below that giant — were doing one specific task and would be better off refactored into a separate module/widget/&#8221;class&#8221;/object. What are they doing in bootstrapper anyway? I scrolled a little further and witnessed more mess — long methods, spread-out functionality and a 4-argument function sneaking somewhere in between. 4 arguments? That&#8217;s just scandalous.</p>
<p>But where to start? Should I just randomly choose a thread to pull? If only I could see the stats for this dashboard object. Some kind of tool to help analyze method length of the entire thing. This way I could start with the messiest part. I could also see overall picture. Heck, I could even use a tool like this on a future project — just to get a feel of how bad things really are. </p>
<p>Well, a thing like that is totally doable, isn&#8217;t it?! </p>
<p>And so that how <a href="http://github.com/kangax/kratko.js">kratko.js</a> was born; a simple tool to help you refactor Javascript.</p>
<h3 id="kratkojs">kratko.js</h3>
<p>There are 3 aspects of refactoring I&#8217;m usually interested in:</p>
<ul>
<li>Which objects/&#8221;classes&#8221; have too many methods?</li>
<li>Which methods do too many things?</li>
<li>Which methods have too many arguments?</li>
</ul>
<p><img src="http://dl.dropbox.com/u/822184/kratko_screenshot_2.png"></p>
<p>Answering these questions and refactoring according to that usually takes care of most of the mess. Objects become more autonomous, by doing only a specific task. Methods become smaller by doing less and having the right level of abstraction. And there&#8217;s no more long-argument functions, order of which no one can ever remember.</p>
<p>This is exactly what kratko.js tries to provide. </p>
<p>kratko.js takes an object and <strong>collects statistics</strong> about its methods and arguments. It can then display that information in a table, allowing to sort by method or argument length. It also provides such numbers as average method/arguments length, and max/min method/arguments length.</p>
<p>It turns out to be pretty useful.</p>
<h3 id="kratko_and_tableviewer">Kratko and TableViewer</h3>
<p>To keep things simple and modular, kratko is made of 2 objects: <code>Kratko</code> which has <code>getStatsFor</code> method, and a <code>TableViewer</code> which could take stats object and display it in an interactive HTML table. If you don&#8217;t care to view results in a fancy HTML table, you can just use <code>Kratko.getStatsFor</code> passing it an object to inspect and receiving an object with elaborate stats for it. The whole thing is a tiny script — about 170 lines long. You can use it in the browser or on the server. All that&#8217;s required is environment that supports function decompilation (in other words, where <code>Function.prototype.toString</code> returns more or less exact representation of a function).</p>
<p><code>TableViewer</code>, on the other hand, is a layer on top of <code>Kratko</code> and provides an outlook of these stats. What&#8217;s really useful, though, is that <code>TableViewer</code> is also <strong>interactive</strong>. You can sort a table by method or argument length, and view actual method contents.</p>
<p><img src="http://dl.dropbox.com/u/822184/kratko_screenshot_3.png"></p>
<p><img src="http://dl.dropbox.com/u/822184/kratko_screenshot_4.png"></p>
<h3 id="getstatsfor_signature">getStatsFor signature</h3>
<p>The signature of <code>Kratko.getStatsFor</code> is pretty straight-forward. Besides having average and min/max numbers, it also stores signatures of each method — just in case you&#8217;d like to iterate over it and do something other than getting an average.</p>
<pre lang="javascript"><code>
{
  methods: {
    name: {
      methodString: ...,
      length: ...,
      argsLength: ...
    }
  },

  totalMethodLength: ...,

  minMethodLength: ...,
  maxMethodLength: ...,

  totalArgsLength: ...,

  minArgsLength: ...,
  maxArgsLength: ...,

  numMethods: ...
}
</code></pre>
<p>So, for example, an object with 2 methods — <code>foo</code> and <code>bar</code>:</p>
<pre lang="javascript"><code>
var obj = {
  foo: function(x, y) {
    return x + y;
  },
  bar: function(a, b, c, d, e, f, g) {
    if (true) {
      // some comment
      alert(123);
    }
  }
};
</code></pre>
<p>..would have this kind of representation:</p>
<pre lang="javascript"><code>
{
  methods: {
    foo: {
      methodString: 'function (x, y) {\n  return x + y;\n}',
      length: 1,
      argsLength: 2
    },
    bar: {
      methodString: 'function (a, b, c, d, e, f, g) {\n  if (true) {\n    //some comment\n    alert(123);\n  }}',
      length: 3,
      argsLength: 7
    }
  },

  totalMethodLength: 4,
  minMethodLength: 1,
  maxMethodLength: 3,

  totalArgsLength: 9,
  minArgsLength: 2,
  maxArgsLength: 7,

  numMethods: 2
}
</code></pre>
<h3 id="bookmarklet">Bookmarklet</h3>
<p>The way I&#8217;ve been using kratko.js so far is via <a href="javascript:(function(){var el=document.createElement('script');el.src='https://github.com/kangax/kratko.js/raw/master/dist/kratko.js';el.onload=function(){var objectName = window.prompt('Which object to inspect?'); if (!objectName) return; new TableViewer(Kratko.getStatsFor(eval(objectName)))};document.getElementsByTagName('head')[0].appendChild(el)})();">simple bookmarklet</a> (<a href="https://github.com/kangax/kratko.js/blob/master/bookmarklet.js">up-to-date source</a>). Open this bookmarklet on the page of a project you&#8217;re working on; tell it which object to inspect (e.g. <code>SomeWidget.prototype</code>, <code>dashboard</code>, etc.) and a stats table will appear. Now you can sort through the methods, and get a nice outlook on what&#8217;s going on.</p>
<p>The bookmarklet and the actual kratko.js script should work on most modern browsers, but I&#8217;ve only tested it on Chrome (13) and Firefox (4). I haven&#8217;t worked on making it cross-browser, but I also haven&#8217;t used anything fancy, so it should be pretty portable.</p>
<h3 id="distribution_graph">Distribution graph</h3>
<p>After working with kratko.js for a bit, I realized that average method length doesn&#8217;t always tell me much. My &#8220;class&#8221; had 100+ methods. Even though some of them were larger than 50 lines long — and so were unacceptable — the average would still come out to be somewhere along 15-20, due to a large number of short, 1-5 -line methods.</p>
<p>I needed a way to quickly see total method size distribution, and so I added a little graph for that. It groups methods by length, showing which ones prevail and where:</p>
<p><img src="http://dl.dropbox.com/u/822184/kratko_screenshot_5.png" alt="Graph of <code>TableViewer.prototype</code>"></p>
<p>I consider the maximum acceptable length of a method in Javascript to be ~20-25 lines long. Anything more than that is usually messy. It takes longer to figure out what's going on, and it's likely a sign of either not enough abstraction, or a method doing too many things (whereas, ideally, it should be doing just one thing — and as clear as possible).</p>
<p>Having said that, distribution graph is really an excellent indication of how "clean" an object is. You obviously want to stay as much on the left side of it as possible. </p>
<p>Here's an example <sup><a href="#bad-graph">[2]</a></sup> (of a "bad" graph):</p>
<p><img src="http://dl.dropbox.com/u/822184/kratko_screenshot_6.png" style="width:960px"></p>
<p>As you can see, those lonely 85 and 56 -liners on the right have to go. There's also that little <strong>nasty bunch</strong> in the 28-43 area. There aren't many of them, thankfully. But they should probably be taken care of as well. Once that's done, the graph would be mainly concentrated in the left 1-20 area. And that would make things much cleaner.</p>
<h3 id="code_style">Code style</h3>
<p>The elephant in the room at this point is the <strong>code style</strong>. How can we base our assessment on a line count, when it could vary so much based on code style? Even though kratko.js does <strong>strip comments and empty lines</strong> <sup><a href="#multiline-comments-issue">[3]</a></sup>, there's still room for deviations. Some prefer single-line statement, others follow more explicit <a href="http://en.wikipedia.org/wiki/Indent_style#Allman_style">Allman style</a>:</p>
<pre lang="javascript"><code>
  if (smth) { smthElse }

  // vs.

  if (smth) {
    smthElse
  }

  // vs.

  if (smth)
  {
    smthElse
  }
</code></pre>
<p>That&#8217;s exactly why it&#8217;s <strong>hard to have any absolute assessments</strong>. Obviously, it&#8217;s important to understand approximate optimal method length rather than follow any exact requirements. Decide for yourself which range you&#8217;d like to stay in, based on code style and personal preference (some people like to keep methods even smaller — under 10 lines, for example). Kratko is simply there to show you an <strong>overall picture</strong>, and guide you through the process of refactoring.</p>
<h3 id="nested_functions">Nested functions</h3>
<p>One last interesting point I&#8217;d like to go over is that of nested functions. When I started to refactor some of the longer methods, I noticed that many of them are long not due to lack of abstraction but due to presence of other, nested functions. Defining a small function right within another one is a pretty common thing in Javascript. It allows to keep things <abbr title="Do Not Repeat yourself">DRY</abbr> and to create necessary abstractions.</p>
<p>Here&#8217;s a simple example:</p>
<pre lang="javascript"><code>
function sort(arr1, arr2) {

  function byFirst(a, b) { return a[0] - b[0] }

  // ...

  if (smth) {
    arr1.sort(byFirst);
  }
  else {
    arr2.sort(byFirst);
  }
}
</code></pre>
<p>Even more importantly, it allows to <strong>scope certain functionality to one place</strong>. When an object has logic that requires more than 50 lines, you can either define few methods right on that object, or create one method with few &#8220;helper&#8221; functions defined right within it.</p>
<p>There&#8217;s certainly nothing inherently wrong in doing so. Those are the same nicely-chunked functions, only defined not on an object but within &#8220;parent&#8221; method. The advantage of such style is more explicit scoping, and the downside is that it could look messy and unclear to someone not familiar with such concepts as hoisting and functions within functions:</p>
<pre lang="javascript"><code>
// Potential problem #1 is that inner function can look confusing

function foo() {
  function bar() { }
}

// Potential problem #2 is that hoisted function declaration (if any) can look confusing

function foo() {
  bar();

  // ... some other code

  function bar() { }
}
</code></pre>
<p>When there&#8217;s more than one nested function, and these nested functions aren&#8217;t just one-liners, there&#8217;s clearly an <strong>additional cognitive burden</strong> involved in method reading. When reading a method, you now need to distill actual logic from these auxilary function declarations. Grouping all declarations at top (or bottom) of the function can help, but there&#8217;s still a slight overhead.</p>
<p>There&#8217;s this one function in Prototype.js which I noticed demonstrates this really well. The function is 76 lines long, so please bear with me. I&#8217;m inserting it untouched just to show how nested functions — especially scattered ones — could make it harder to read the method and follow its logic. It&#8217;s a good thing Prototype.js has always kept its variable/function names as explicit and descriptive as possible — something I&#8217;ve always loved about it — or reading this function would be even harder:</p>
<pre lang="javascript"><code>
function (methods) {
  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;

  if (!methods) {
    Object.extend(Form, Form.Methods);
    Object.extend(Form.Element, Form.Element.Methods);
    Object.extend(Element.Methods.ByTag, {
      "FORM":     Object.clone(Form.Methods),
      "INPUT":    Object.clone(Form.Element.Methods),
      "SELECT":   Object.clone(Form.Element.Methods),
      "TEXTAREA": Object.clone(Form.Element.Methods)
    });
  }

  if (arguments.length == 2) {
    var tagName = methods;
    methods = arguments[1];
  }

  if (!tagName) Object.extend(Element.Methods, methods || { });
  else {
    if (Object.isArray(tagName)) tagName.each(extend);
    else extend(tagName);
  }

  function extend(tagName) {
    tagName = tagName.toUpperCase();
    if (!Element.Methods.ByTag[tagName])
      Element.Methods.ByTag[tagName] = { };
    Object.extend(Element.Methods.ByTag[tagName], methods);
  }

  function copy(methods, destination, onlyIfAbsent) {
    onlyIfAbsent = onlyIfAbsent || false;
    for (var property in methods) {
      var value = methods[property];
      if (!Object.isFunction(value)) continue;
      if (!onlyIfAbsent || !(property in destination))
        destination[property] = value.methodize();
    }
  }

  function findDOMClass(tagName) {
    var klass;
    var trans = {
      "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
      "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
      "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
      "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
      "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
      "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
      "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
      "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
      "FrameSet", "IFRAME": "IFrame"
    };
    if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName.capitalize() + 'Element';
    if (window[klass]) return window[klass];

    var element = document.createElement(tagName),
        proto = element['__proto__'] || element.constructor.prototype;

    element = null;
    return proto;
  }

  var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
   Element.prototype;

  if (F.ElementExtensions) {
    copy(Element.Methods, elementPrototype);
    copy(Element.Methods.Simulated, elementPrototype, true);
  }

  if (F.SpecificElementExtensions) {
    for (var tag in Element.Methods.ByTag) {
      var klass = findDOMClass(tag);
      if (Object.isUndefined(klass)) continue;
      copy(T[tag], klass.prototype);
    }
  }

  Object.extend(Element, Element.Methods);
  delete Element.ByTag;

  if (Element.extend.refresh) Element.extend.refresh();
  Element.cache = { };
}
</code></pre>
<p>It&#8217;s also worth mentioning that &#8220;problem&#8221; with nested function can easily be taken care of by moving these auxilary functions into a closure:</p>
<pre lang="javascript"><code>
var foo = {

  bar: (function(){

    function aux1() { }
    function aux2() { }

    return function() {
      // ...
      aux1();
      aux2();
    };

  })()
}
</code></pre>
<p>kratko.js obviously doesn&#8217;t know about such &#8220;hidden&#8221; functions, and so <code>bar</code> now &#8220;looks&#8221; like this:</p>
<pre lang="javascript"><code>
function() {
  // ...
  aux1();
  aux2();
}
</code></pre>
<p>All of these problems are arguably non-issues, so apply your own judgement and preference when dealing with this kind of things. If you see a method that&#8217;s long due to nested functions, and you&#8217;re OK with nested functions, move on to something else. The reason I&#8217;m bringing this up is to show once again that kratko.js measurements are not absolute and should be taken into consideration rather then followed strictly.</p>
<h3 id="what_does_future_hold">What does future hold?</h3>
<p>I was pondering what else could a tool like kratko.js do. Some of the ideas that came to my mind:</p>
<ul style="padding-left:0">
<li>
<p>Measure method width (to catch methods that are wider than 100/80/72 characters long, depending on your preference)</p>
</li>
<li>
<p>Count statements rather than lines; this could make both of these snippets equal to 1 line long, rather than 10-to-1:</p>
<pre lang="javascript"><code>
if
(
true
)
{
alert
(
1
)
}

// vs.

if (true) alert(1)
</code></pre>
</li>
<li>
<p>Syntax highlight the code (of the methods)</p>
</li>
<li>
<p>Support navigating through objects (e.g. to get to <code>jQuery.fn</code> from <code>jQuery</code> or to <code>fabric.Element.prototype</code> from <code>fabric.Element</code>)</p>
</li>
<li>
<p>Integration with other services (e.g. pre-commit hook, pre-production quality check, etc.)</p>
</li>
<li>
<p>&lt;insert your idea here></p>
</li>
</ul>
<h3 id="source_unit_tests">Source, unit tests</h3>
<p>kratko.js is licensed under MIT and is free for any kind of use (just leave attribution, please, and contribute if/what you can). The <a href="http://github.com/kangax/kratko.js">source is on github</a>. So are unit tests. If you want to change, fix, or suggest something — I welcome any pull requests.</p>
<p>Use it to make your code better. Have fun!</p>
<p class="footnote" id="on-refactoring">
  <sup>[1]</sup> If you don&#8217;t have <a href="http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672">&#8220;Refactoring&#8221;</a> or <a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882">&#8220;Clean Code&#8221;</a> on a bookshelf, do yourself a favor and go get them now. This will be totally worth it.
</p>
<p class="footnote" id="bad-graph">
  <sup>[2]</sup> This &#8220;bad&#8221; graph is actually of my <a href="https://github.com/kangax/fabric.js/blob/gh-pages/src/element.class.js#L1725-1829">fabric.Element.prototype</a>. Embarassing, I know. Will be fixed soon.
</p>
<p class="footnote" id="multiline-comments-issue">
  <sup>[3]</sup> Note that multiline comments stripping is not very bulletproof and can have false results in certain (rare) cases. it does work well most of the time, though.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerfectionKills?a=pPJxgB4qRKM:Yx1OLWGDmIs:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerfectionKills?i=pPJxgB4qRKM:Yx1OLWGDmIs:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerfectionKills/~4/pPJxgB4qRKM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/refactoring-javascript-with-kratko-js/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		<feedburner:origLink>http://perfectionkills.com/refactoring-javascript-with-kratko-js/</feedburner:origLink></item>
		<item>
		<title>Unnecessarily comprehensive look into a rather insignificant issue of global objects creation</title>
		<link>http://feedproxy.google.com/~r/PerfectionKills/~3/YH2qGtd5Mik/</link>
		<comments>http://perfectionkills.com/unnecessarily-comprehensive-look-into-a-rather-insignificant-issue-of-global-objects-creation/#comments</comments>
		<pubDate>Tue, 01 Mar 2011 16:00:07 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[ECMA-262]]></category>
		<category><![CDATA[ES5]]></category>
		<category><![CDATA[eval]]></category>
		<category><![CDATA[strict-mode]]></category>
		<category><![CDATA[undeclared assignment]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=395</guid>
		<description><![CDATA[I noticed this code few days ago — in one of the &#8220;modules&#8221; of an internal app I&#8217;m working on — which looked like this: if (MyApp == null) { var MyApp = {} } This was at the beginning of the file, and was obviously a way to define global &#8220;namespace&#8221; object, if one [...]]]></description>
			<content:encoded><![CDATA[<p>I noticed this code few days ago — in one of the &#8220;modules&#8221; of an internal app I&#8217;m working on — which looked like this:</p>
<pre lang="javascript"><code>
if (MyApp == null) {
    var MyApp = {}
}
</code></pre>
<p>This was at the beginning of the file, and was obviously a way to define global &#8220;namespace&#8221; object, if one didn&#8217;t exist. The condition in this particular case, however, looked rather unusual — <code>if (MyApp == null)</code>. It got me thinking about the <em>ridiculous</em> number of ways in which it is possible to define a global object in Javascript.</p>
<p>I&#8217;m sure you&#8217;ve seen the variations of this kind:</p>
<pre lang="javascript"><code>
if (typeof MyApp == 'undefined') {
  var MyApp = { };
}
</code></pre>
<p>or:</p>
<pre lang="javascript"><code>
if (!window.MyApp) {
  window.MyApp = { };
}
</code></pre>
<p>or maybe even something as strange as:</p>
<pre lang="javascript"><code>
if (MyApp === undefined) {
  MyApp = { };
}
</code></pre>
<p>But have you ever wondered about the difference between these? Are any of them &#8220;better&#8221; than the other ones, and why? Is there a particular way you prefer, and for which reason?</p>
<p>If we were to look into some of the possible global object creation patterns, it turns out there&#8217;s quite a bit of interesting little details (and traps) here and there. What do you mean they&#8217;re not interesting? Of course they are! :)</p>
<p>As a fun exercise, let&#8217;s go over some of the more popular variations, explaining the inner workings of each one of them. We&#8217;ll take a look at troublesome ones; those that are more compatible than others; and those that differ depending on whether implementation follows ES3 or ES5 rules. Hopefully, you&#8217;ll also learn a thing or two about ECMAScript while we&#8217;re at it.</p>
<h3 id="how_many_ways_to_skin_a_cat">How many ways to skin a cat?</h3>
<p>So what are the options for creating a global object if one doesn&#8217;t exist? Well, let&#8217;s see. There are <strong>conditions</strong>, used as expression in an <code>if</code> statement. And there are <strong>actions</strong> used as the inner statement in an <code>if</code> statement.</p>
<pre lang="javascript"><code>
if (condition) {
  action
}
</code></pre>
<p>Even if we&#8217;re not using <code>if</code> statement, the general pattern of condition + action is still in effect:</p>
<pre lang="javascript"><code>
condition &amp;&amp; action
!condition || action
// etc.
</code></pre>
<p>The lists of conditions and actions might look like this (I&#8217;ll be using <code>MyApp</code> &#8220;name&#8221; as an example):</p>
<p>Conditions:</p>
<pre lang="javascript"><code>
  !MyApp
  !window.MyApp
  !this.MyApp
  !global.MyApp
  typeof MyApp == "undefined"
  typeof MyApp != "object"
  MyApp === undefined
  MyApp == null
  "MyApp" in window
  window.hasOwnProperty("MyApp")
</code></pre>
<p>Actions:</p>
<pre lang="javascript"><code>
  var MyApp = { }
  window.MyApp = { }
  this.MyApp = { }
  global.MyApp = { } // where `global` references global object
  MyApp = { }
</code></pre>
<p>There are undoubtedly other similar variations, such as using bracket notation instead of dot notation — <code>if (window['MyApp']) { ... }</code>, or more obscure ones like <code>eval('var MyApp = ...')</code>, but we&#8217;ll omit those for the sake of brevity. Arguably, some of the items in this list are rather similar to each other, like <code>window.MyApp</code>, <code>this.MyApp</code>, and <code>global.MyApp</code> — after all, they are all assignments to a property of global object — but I&#8217;d like to show the important difference in each one of them, which is why we&#8217;ll look at them separately.</p>
<p>I promise not to go over all of the 50+ possible combinations. Only a handful of them.</p>
<h3 id="patterns_overview">Patterns overview</h3>
<h4 id="1_typeof_variable_declaration">1) typeof + variable declaration</h4>
<pre lang="javascript"><code>
if (typeof MyApp == 'undefined') {
  var MyApp = { };
}
</code></pre>
<p>This is probably the most popular variation. Good old variable declaration, and a typeof check. When executed as global code, it creates a global variable (if one doesn&#8217;t exist) and assigns an object reference to it. What&#8217;s important to understand about this snippet is that variable declaration — similar to function declaration — <strong>follows the so-called &#8220;hoisting&#8221; behavior</strong>. In other words, <code>MyApp</code> variable is created before any statements in the current scope are executed. This is why the snippet is functionally identical to:</p>
<pre lang="javascript"><code>
var MyApp;
...
if (typeof MyApp == 'undefined') {
  MyApp = { };
}
</code></pre>
<p>When <code>MyApp</code> is already defined and references something, <code>typeof MyApp != 'undefined'</code> check does not succeed and <code>MyApp</code> is not overwritten. The declaration of <code>MyApp</code> does nothing since binding already exists in this scope. However, if <code>MyApp</code> doesn&#8217;t yet exist, <code>typeof MyApp</code> evaluates to &#8220;undefined&#8221;, and <code>MyApp</code> is assigned a reference to a newly created object. The reason <code>typeof MyApp</code> evaluates to &#8220;undefined&#8221; is because at that point MyApp is already declared and has an <code>undefined</code> value (as all undeclared variables do).</p>
<h4 id="2_boolean_conversion_variable_declaration">2) boolean conversion + variable declaration</h4>
<pre lang="javascript"><code>
if (!MyApp) {
  var MyApp = { };
}
</code></pre>
<p>Another common version is the same as the previous one, only with <code>typeof</code> check replaced by a boolean conversion one. This one is clearly shorter but is it just as reliable? I remember being confused about it a while back. Shouldn&#8217;t <code>MyApp</code> throw a <code>ReferenceError</code> if <code>MyApp</code> isn&#8217;t declared — I thought. My fears were certainly unfounded. The &#8220;hoisting&#8221; behavior of variable declarations <strong>prevents ReferenceError from occurring</strong> here. Similarly to the previous example, let&#8217;s see a functionally identical version of a snippet:</p>
<pre lang="javascript"><code>
var MyApp;
...
if (!MyApp) {
  MyApp = { };
}
</code></pre>
<p><code>var MyApp</code> that&#8217;s inside the block, hoists <code>MyApp</code> declaration to the top of the scope. By the time execution gets to the <code>if</code> statement, <strong><code>MyApp</code> is already declared</strong> and has an <code>undefined</code> value. <code>if (!MyApp)</code> can never throw a <code>ReferenceError</code>, since the variable is always declared.</p>
<h4 id="3_boolean_conversion_undeclared_assignment">3) boolean conversion + undeclared assignment</h4>
<pre lang="javascript"><code>
if (!MyApp) {
  MyApp = { };
}
</code></pre>
<p>Sometimes a perfectly good second version is taken to the &#8220;next level&#8221; with this unpleasant variation. Unlike previous example, there&#8217;s no variable declaration here; only an assignment. When <code>MyApp</code> doesn&#8217;t exist, <code>!MyApp</code> expression throws <code>ReferenceError</code> for exactly this reason — the variable is never declared, and the access to it should throw! This version is hardly practical, but it&#8217;s good to understand why it doesn&#8217;t &#8220;work&#8221;.</p>
<h5 id="undeclared_assignment">Undeclared assignment</h5>
<p>Before we move further, take a closer look at <code>MyApp = { }</code> line. Anything looks suspicious there?</p>
<p>This is a so-called <strong>undeclared assignment</strong>. Instead of declaring a variable via a variable statement (i.e. <code>var MyApp = { }</code>), <code>MyApp</code> is being assigned a value directly. In ECMAScript, when something is being assigned to non-existing variable, the variable with that name is created on a global object and becomes available to any code. Well, to be more precise, it becomes a global property, rather than a variable, but this subtle difference is not important now.</p>
<p>So <code>MyApp = { }</code> creates a global <code>MyApp</code> property, then assigns a newly created object reference to it.</p>
<p>Note how very much <code>MyApp = { }</code> is different from <code>var MyApp = { }</code>. The former one — undeclared assignment — <strong>creates a global property</strong>, whereas latter one — variable declaration — <strong>creates a local variable</strong>.</p>
<p>Undeclared assignments are historically considered a bad practice. They lead to confusion and increase the risk of global collisions. There are also certain browser bugs, such as that in IE (MSHTML DOM), where undeclared assignment results in an error if element with same id/name exists in the document. There&#8217;s a big chance for beginner to forget <code>var</code> and end up creating an unwanted global property. Or simply consider var&#8217;less version to be similar to that with the <code>var</code>. Or not even know about having to use <code>var</code> — after all, plain assignment seems to work just fine.</p>
<p>Since undeclared assignments are such a misleading part of the language, ECMAScript 5 — newest version of ECMAScript — specifies that when they occur in a strict mode, a ReferenceError should be thrown. This makes for more robust code with less chance for unexpected errors. And since strict mode is more or less a future direction of the language, it makes sense to <strong>avoid undeclared assignments</strong> as if they never existed.</p>
<h4 id="4_typeof_undeclared_assignment">4) typeof + undeclared assignment</h4>
<pre lang="javascript"><code>
if (typeof MyApp == 'undefined') {
  MyApp = { };
}
</code></pre>
<p>Another harmful variation, and unfortunately the one that actually &#8220;works&#8221;. Note how there&#8217;s still an undeclared assignment, but the condition is now replaced with a <code>typeof</code> check. <code>typeof</code> check is exactly what makes all of this work, unlike plain variable access in the previous example. In ECMAScript, when <code>typeof</code> is passed an undeclared identifier, it&#8217;s specified to return string &#8220;undefined&#8221;. This kind of leniency exists on purpose — <code>typeof</code> is meant to be used with undeclared identifiers; it doesn&#8217;t throw (as regular variable access does) but returns &#8220;undefined&#8221; instead.</p>
<p>So when <code>MyApp</code> doesn&#8217;t exist and <code>if</code> expression succeeds, <code>MyApp = { }</code> is evaluated and creates a global <code>MyApp</code> property. The problem here is that <code>MyApp = { }</code> is still an <strong>undeclared assignment</strong> and so has all the same problems as undeclared assignment from the previous example.</p>
<h4 id="5_property_access_on_window">5) property access on window</h4>
<pre lang="javascript"><code>
if (!window.MyApp) {
  window.MyApp = { };
}
</code></pre>
<p>Stepping away from variable declarations and undeclared assignments, which other ways are there to create a global property? </p>
<p>Well, by assigning directly to a global object of course. In browsers global object is often referenced through global <code>window</code> property. So one of the ways to create a property on a global object is by assigning to property of <code>window</code>. This solution is almost perfect, except for two drawbacks. </p>
<p>First, it makes code less portable, as there is a reliance on presence of global <code>window</code> property. If you wanted to run it in a non-browser environment (V8, Rhino, WScript, etc.) <code>window</code> is likely to be non-existent there.</p>
<p>Second problem is a bit more vague. It&#8217;s relevant to browser environments only, and it&#8217;s about <code>window</code> not referencing global object directly. HTML5 defines <code>window</code> to <a href="http://www.whatwg.org/specs/web-apps/current-work/?slow-browser#dom-window">reference not global object, but so-called WindowProxy object</a>. Even though all operations performed on WindowProxy must also be performed on the Window object, there are few existing quirks — notably in Internet Explorer — where <a href="http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/22e6b2d147f57ee5">global (variable) object and <code>window</code> are not fully interchangeable</a> (<a href="https://groups.google.com/group/comp.lang.javascript/msg/c1572441853282c6">more evidence</a>).</p>
<p>Curiously, current HTML5 draft also says that <code>window</code> <strong>typically references a Global Object</strong>, which makes it a non-requirement. In practice, however, <code>window</code> almost always references Global Object (or at least an object that <strong>acts</strong> as if it was a global object).</p>
<h4 id="6_property_access_on_this">6) property access on this</h4>
<p>If you don&#8217;t want to rely on browser-only <code>window</code>, the most straightforward way to assign to a global object is by creating a reference that definitely gives us a Global Object. How to create such reference? Well, since we&#8217;re in global code, we can freely use <code>this</code> keyword.</p>
<pre lang="javascript"><code>
if (!this.MyApp) {
  this.MyApp = { };
}
</code></pre>
<p>This works beautifully, and should create a global object in any respectable (i.e. ECMAScript-compliant) implementation. Note, however, that this code can only be run in global scope to ensure that <code>this</code> references global object. Of course you could also run it non-globally as long as <code>this</code> keeps referencing global object:</p>
<pre lang="javascript"><code>
var myObject = {
  myMethod: function() {
    ...
    if (!this.MyApp) {
      this.MyApp = { };
    }
  }
};

// call method with `this` referencing global object rather than `myObject` 

myObject.myMethod.call(this);
</code></pre>
<p>The requirement to be able to create global object from within non-global code might seem contrived. Yet, I&#8217;ve seen quite few times how javascript files — representing different &#8220;modules&#8221; — were concatenated together and wrapped into another, global self-executing function. Or the code would be eval&#8217;d after being retrieved from the server via XHR. During evaluation, it would be executed in the scope of a caller, not in the global scope.</p>
<p>This kind of &#8220;global object passing&#8221; could certainly become cumbersome. If only there was a way to get access to global object from within any scope. Well, there certainly is.</p>
<h4 id="7_property_access_on_global">7) property access on global</h4>
<p>The easiest way to achieve this is by creating a globally-accessible unique property referencing global object:</p>
<pre lang="javascript"><code>
// from within global code
var global = this;
</code></pre>
<p>.. which brings us to the next variation of global object creation:</p>
<pre lang="javascript"><code>
if (!global.MyApp) {
  global.MyApp = { };
}
</code></pre>
<p>This snippet could now be executed from anywhere — as long as <code>global</code> binding is not shadowed by anything in the executing scope.</p>
<pre lang="javascript"><code>
(function(global){

  // this obviously won't work since `global` is now a local variable and has a value of `undefined`.

  if (!global.MyApp) {
    globa.MyApp = { };
  }

})();
</code></pre>
<p>We solved the problem of not being able to run code from anywhere, but at the expense of having an extra global property. We&#8217;ve also introduced a requirement to actually <strong>create</strong> that global property. If our code is run in unknown environment, where it&#8217;s not possible to create this global object shortcut, this kind of solution is out of the question. Additionally, there&#8217;s a chance of collisions if another code defines global <code>global</code> property referencing something other than global object.</p>
<p>This is disastrous. What to do?</p>
<h5 id="global_object_retrieval">Global object retrieval</h5>
<p>In ECMAScript 3 — it turns out — there&#8217;s a very easy way to retrieve global object from within any code. The beauty of the following solution is also that it&#8217;s not affected by local shadowing. It&#8217;s pretty much the perfect way to get access to global object:</p>
<pre lang="javascript"><code>
var global = (function(){return this})();
</code></pre>
<p>The idea is simple. In ES3, when function is called as a function (not as a method; more precisely — <a href="http://bclary.com/2004/11/07/#a-11.2.3">as a non-reference or as a reference with <code>null</code> base object</a>) its <code>this</code> is set to reference global object. When <code>(function(){ ... })()</code> is executed, it evaluates to a non-reference, so it&#8217;s invoked with <code>this</code> referencing global object.</p>
<p>Alternatively, we could have created a reference with <code>null</code> base object, which would also execute function with <code>this</code> referencing global object:</p>
<pre lang="javascript"><code>
function f(){return this}
var global = f();
</code></pre>
<p>.. but that wouldn&#8217;t be as short and concise.</p>
<p>Great! We can now have global object from within anywhere. Is there a catch?</p>
<h5 id="ecmascript_5_strict_mode">ECMAScript 5 strict mode</h5>
<p>Well, yes, kind of. The catch is ECMAScript 5 and its newly-introduced <a href="https://developer.mozilla.org/en/JavaScript/Strict_mode">strict mode</a>. In ES5 strict mode, <code>this</code> no longer references global object in the above two cases:</p>
<pre lang="javascript"><code>
"use strict";
(function(){return this})(); // undefined

function f(){return this}
f(); // undefined
</code></pre>
<p>The rationale for this was, supposedly, to increase security by limiting access to global object. There is, however, a workaround and it involves <strong>indirect eval call</strong> (which I <a href="http://perfectionkills.com/global-eval-what-are-the-options/#indirect_eval_call_theory">explained in the past</a>):</p>
<pre lang="javascript"><code>
"use strict";
var global = (1,eval)("this");
</code></pre>
<p>Indirect eval evaluates code in global scope, and <a href="http://es5.github.com/#x10.4.2">MUST set <code>this</code> to reference global object</a>. So <code>(1,eval)('this')</code>, which is an indirect eval call, should evaluate to a global object. </p>
<p>The downside of this workaround is potential shadowing of <code>eval</code> by something other than built-in <code>eval</code>. The solution is certainly not as robust as <code>(function(){return this})()</code> one, which can be used in ES3 and ES5-non-strict code.</p>
<p>So to summarize:</p>
<pre lang="javascript"><code>
var global = (function(){return this})(); // ES3, ES5 non strict
var global = (1,eval)('this'); // ES5 strict
</code></pre>
<p>In our current world of just-appearing ES5-compliant implementations, it&#8217;s hard to come up with a reliable cross-platform solution. Should we use ES3-ES5-non-strict snippet or ES5-strict one? The latter one sounds like a more future-proof solution, but reliance on indirect eval makes it a moving target: as <a href="http://perfectionkills.com/global-eval-what-are-the-options/#indirect_eval_call_in_practice">we&#8217;ve seen before</a>, indirect eval behavior varies across browsers. </p>
<p>Perhaps we can <strong>assume</strong> that browsers with strict mode support also follow ES5-compliant indirect eval behavior? In that case solution is simple:</p>
<pre lang="javascript"><code>
"use strict";
var global = (function(){ return this || (1,eval)('this') })();
</code></pre>
<p>Implementations that don&#8217;t support strict mode, should evaluate left-hand side of <code>||</code> expression — <code>this</code>, which would be a global object and as any object be truthy. Implementations that DO support strict mode, should evaluate right-hand side of an expression since <code>this</code> would be <code>undefined</code>. Right-hand side should then evaluate to a global object — if <code>eval</code> still references built-in function of course.</p>
<p>This solution is arguably too verbose so it might not be desirable in all cases.</p>
<h4 id="8_property_access_variable_declaration">8) property access + variable declaration</h4>
<p>Another common pattern is the one that <strong>combines</strong> any of the previously discussed solutions. For example, property check as condition and variable declaration as action:</p>
<pre lang="javascript"><code>
if (!window.MyApp) {
  var MyApp = { };
}
</code></pre>
<p>or <code>typeof</code> check as condition and property creation as an action:</p>
<pre lang="javascript"><code>
if (typeof MyApp == 'undefined') {
  window.MyApp = { };
}
</code></pre>
<p>Are there any problems with this variation? Benefits?</p>
<p>Well, first version can obviously only work when run from within global code; we need variable declaration to create global binding. The potential problem with this snippet is that we check existence of property on <code>window</code> but create it on global object. If <code>window</code> doesn&#8217;t reference global object, there&#8217;s a room for discrepancy. We could use previously discussed <code>this</code> or <code>global</code> instead of <code>window</code> — to refer to a global object:</p>
<pre lang="javascript"><code>
if (!this.MyApp) {
  var MyApp = { };
}
</code></pre>
<p>In this case, the snippet is not much different from the first example:</p>
<pre lang="javascript"><code>
if (typeof MyApp == 'undefined') {
  var MyApp = { };
}
</code></pre>
<p>The only subtle difference here is that <code>this.MyApp</code> check proceeds when <code>this.MyApp</code> evaluates to something <strong>falsy</strong> (0, &#8221;, NaN, null, undefined, false), whereas <code>typeof MyApp == "undefined"</code> — only when <code>MyApp</code> evaluates to <code>undefined</code>:</p>
<pre lang="javascript"><code>
var MyApp = '';
...

if (!this.MyApp) {
  // this statement is executed; MyApp is overwritten
  var MyApp = { };
}
if (typeof MyApp == 'undefined') {
  // this statement is not executed; MyApp is not overwritten
  var MyApp = { };
}
</code></pre>
<p>Since both <code>this.MyApp = { }</code> and <code>var MyApp = { }</code> will create global <code>MyApp</code> binding, the only difference here is that <strong>former one makes it deletable, while latter one doesn&#8217;t</strong>. Other than that, there is no difference — both operate on a global object when run from within global code. At least in theory. In practice, though, there has been some evidence of IE having different objects as global variable object and <code>window</code> object. For best cross-browser results, I would suggest to <strong>avoid mixing them up</strong> like this.</p>
<h4 id="9_typeof_8220object8221">9) typeof &#8220;object&#8221;</h4>
<p>Sometimes <code>typeof MyApp == 'undefined'</code> check is replaced with the opposite one — <code>typeof MyApp != 'object'</code>. </p>
<pre lang="javascript"><code>
  if (typeof MyApp != 'object') {
    ...
  }
</code></pre>
<p>There isn&#8217;t much difference here, of course, except that <code>typeof != 'object'</code> check will also catch any other non-object and non-undefined values; pretty much all primitives except <code>undefined</code>:</p>
<pre lang="javascript"><code>
  var MyApp = "trolololololo";

  if (typeof MyApp != 'object') {
    MyApp = { }; // MyApp is overwritten
  }
</code></pre>
<h4 id="10_null_and_undefined">10) == null and === undefined</h4>
<p>Other times, <code>typeof</code> check is replaced with direct comparison with <code>undefined</code> or <code>null</code> values:</p>
<pre lang="javascript"><code>
if (MyApp === undefined) {
  var MyApp = { };
}

// or

if (MyApp == null) {
  var MyApp = { };
}
</code></pre>
<p>The second example is what I mentioned in the beginning and what got me surprised in the first place. As you probably know, comparing to <code>null</code> via equality operator (<code>==</code>) returns <code>true</code> when value is either <code>null</code> or <code>undefined</code>. This is why it allows to catch undeclared variables which have <code>undefined</code> values.</p>
<p>If you think about it, there&#8217;s really no reason to use this kind of check though. Even though it&#8217;s shorter than <code>typeof</code>, comparing to <code>undefined</code> is more fragile, since <code>undefined</code> is a writable property in ES3 (which is why — without taking precautions — it has been generally recommended against). Comparing to <code>null</code> is safer but is still unnecessary; <code>!MyApp</code> is just enough and is even shorter.</p>
<h4 id="11_in_and_hasownproperty">11) <code>in</code> and <code>hasOwnProperty</code></h4>
<p>There are even more exotic beasts such as those using <code>in</code> operator or <a href="https://mail.mozilla.org/pipermail/es-discuss/2011-February/012746.html"><code>hasOwnProperty</code> method</a>.</p>
<pre lang="javascript"><code>
if (!('MyApp' in this)) {
  this.MyApp = { };
}

if (!this.hasOwnProperty('MyApp')) {
  this.MyApp = { };
}
</code></pre>
<p>Using <code>in</code> is almost identical to using plain boolean conversion — <code>if (!MyApp) ...</code>. The only difference is that <code>in</code> will &#8220;catch&#8221; global properties with any values, whereas boolean conversion-based one — only those that have truthy values. Similarly to <code>typeof ... == "undefined"</code> check, <code>in</code> will catch both — undeclared variables and variables with undefined values.</p>
<p><code>hasOwnProperty</code>, on the other hand, is a bit more strict. Even though irrelevant in our case, it&#8217;s worth remembering that <code>hasOwnProperty</code> will catch only those properties that exist directly on a global object. That means nothing from global object&#8217;s prototype chain, which could include <code>Object.prototype</code>, <code>Window.prototype</code>, etc.</p>
<pre lang="javascript"><code>
this.hasOwnProperty('localStorage'); // false
'localStorage' in this; // true

this.hasOwnProperty('alert'); // false
'alert' in this; // true

this.hasOwnProperty('toString'); // false
'toString' in this; // true

var x;
this.hasOwnProperty('x'); // true
'x' in this; // true
</code></pre>
<h4 id="12_operator">12) || operator</h4>
<pre lang="javascript"><code>
global.MyApp || (global.MyApp = { });
this.MyApp = this.MyApp || { };
typeof MyApp == 'undefined' &amp;&amp; (global.MyApp = { });
</code></pre>
<p>A slightly different way to write #5, #6, or #7 is using <code>||</code> operator. The functionality is the same; this is only a matter of preference.</p>
<h3 id="takeaway_points">Takeaway points</h3>
<p>So there you have it. A quick rundown through some of the most popular options. To summarize:</p>
<ul>
<li>Avoid undeclared assignments. They are a &#8220;dying&#8221; part of the language.</li>
<li>Assigning to <code>window</code> is not completely cross-platform; using <code>this</code> (or retrieving global object) is more portable.</li>
<li>Retrieving global object is iffy. You can use <code>(function(){ return this || (1,eval)('this') })()</code> which should work in ES3, ES5 and ES5-strict.</li>
<li>Some variations (e.g. variable assignment) work only in global scope; others (e.g. assignment to window) — from within any.</li>
<li>No need to perform <code>typeof "undefined"</code>, or <code>=== undefined</code> checks; plain <code>!</code> operator works just as well, as long as variable is created via declaration.</li>
<li>When in global scope, the easiest &amp; simplest version to create global object is <code>if (!MyApp) var MyApp = ...</code></li>
<li>When object needs to be deleted at some point after creation, property assignment is the way to go: <code>if (!this.MyApp) this.MyApp = ...</code> (substituting <code>this</code> with <code>window</code> or <code>global</code> as necessary)</li>
<li>Avoid mixing <code>this</code>/<code>window</code>/<code>global</code> and global variable object (used to create property during variable declaration); they could be different objects.</li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerfectionKills?a=YH2qGtd5Mik:Jc16u_IHvhQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerfectionKills?i=YH2qGtd5Mik:Jc16u_IHvhQ:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerfectionKills/~4/YH2qGtd5Mik" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/unnecessarily-comprehensive-look-into-a-rather-insignificant-issue-of-global-objects-creation/feed/</wfw:commentRss>
		<slash:comments>54</slash:comments>
		<feedburner:origLink>http://perfectionkills.com/unnecessarily-comprehensive-look-into-a-rather-insignificant-issue-of-global-objects-creation/</feedburner:origLink></item>
		<item>
		<title>A closer look at expression closures</title>
		<link>http://feedproxy.google.com/~r/PerfectionKills/~3/-VCPXGm7V0Q/</link>
		<comments>http://perfectionkills.com/a-closer-look-at-expression-closures/#comments</comments>
		<pubDate>Mon, 17 Jan 2011 20:37:46 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[ECMA-262]]></category>
		<category><![CDATA[Harmony]]></category>
		<category><![CDATA[Mozilla]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=379</guid>
		<description><![CDATA[#expression-closure-tests li { margin-bottom: 30px; } #expression-closure-tests li .q { margin-bottom: 0.5em; } #expression-closure-traits li { list-style-position: inside; } I was recently working hacking on something in Firebug console and remembered about expression closures — a language addition, introduced in Mozilla&#8217;s JavaScript 1.8. The concise explanation on MDC captures the essence of expression closures: This [...]]]></description>
			<content:encoded><![CDATA[<style>
  #expression-closure-tests li { margin-bottom: 30px; }
  #expression-closure-tests li .q { margin-bottom: 0.5em; }
  #expression-closure-traits li { list-style-position: inside; }
</style>
<p>I was recently <del>working</del> hacking on something in Firebug console and remembered about <a href="https://developer.mozilla.org/en/new_in_javascript_1.8#Expression_closures_(Merge_into_own_page.2fsection)">expression closures</a> — a language addition, introduced in <a href="https://developer.mozilla.org/en/new_in_javascript_1.8">Mozilla&#8217;s JavaScript 1.8</a>. The concise explanation on MDC captures the essence of expression closures:</p>
<p><cite>This addition is nothing more than a shorthand for writing simple functions, giving the language something similar to a typical Lambda notation. [&#8230;] This syntax allows you to leave off the braces and &#8216;return&#8217; statement &#8211; making them implicit. There is no added benefit to writing code in this manner, other than having it be syntactically shorter.</cite></p>
<p>And that&#8217;s exactly what I used it for — to quickly experiment with something, shortening function expressions to save on typing.</p>
<p>MDC also gives a simple example, showcasing a function written using expression closure:</p>
<pre lang="javascript"><code>
  // Regular syntax
  function() { return x * x }

  // Expression closure
  function(x) x * x
</code></pre>
<p>As you can see, expression closure is essentially a more concise way to create a function. Based on MDC, expression closure allows us to drop &#8220;return&#8221; and braces denoting function body.</p>
<p>The information on MDC, however, was so tiny that I became curious about some of the finer details of how expression closures (EC from now on) work. Can they only be used to create function expressions? How about function declarations? What about <strong>named</strong> function expressions? Is <code>function() ...</code> always identical to <code>function(){return ...}</code> no matter what&#8217;s in the <code>...</code> (function body)? And what are these &#8220;simple functions&#8221; MDC is talking about?</p>
<p>There was no answer to any of these questions, so I decided to quickly investigate this funky language addition a bit deeper. These are some of my findings; you&#8217;ll see that certain behavior isn&#8217;t always obvious.</p>
<p>Letting the code speaks for itself, here&#8217;s is a list of questions followed by simple tests, attempting to answer those questions. Feel free to skip to the <a href="#main_features">next section</a> for a shorter overview of these findings.</p>
<h3 id="tests">Tests</h3>
<ol id="expression-closure-tests">
<li>
<p class="q">Can EC be used to create function declarations (not just function expressions)?</p>
<p>Yes.</p>
<pre lang="javascript"><code>
function f(x, y) x + y
typeof f; // "function"
</code></pre>
</li>
<li>
<p class="q">What about named function expressions?</p>
<p>Works as expected.</p>
<pre lang="javascript"><code>
typeof (function f(x, y) x + y); // "function"
</code></pre>
</li>
<li>
<p class="q">How does EC affect function representation?</p>
<p>As usual, but does not include curly braces (or &#8220;return&#8221; keyword)!</p>
<pre lang="javascript"><code>
String(function (x) x + x ); // "function (x) x + x;"
</code></pre>
</li>
<li>
<p class="q">What about non-standard `name` property?</p>
<p>Works as expected.</p>
<pre lang="javascript"><code>
function foo(x, y) x + y;
foo.name; // "foo"
</code></pre>
</li>
<li>
<p class="q">How about immediately invoked function expression?</p>
<p>Works fine.</p>
<pre lang="javascript"><code>
(function(x, y) x + y)(1, 2); // 3
</code></pre>
</li>
<li>
<p class="q">What about immediately invoked function expression without wrapping parens?</p>
<p>Not so fast!</p>
<pre lang="javascript"><code>
var f1 = (function(x, y) x + y)(1, 2);
var f2 = function(x, y) x + y (1, 2);

f1; // 3
f2; // function(x, y) x + y(1, 2)
</code></pre>
<p>As you can see, <code>(1, 2)</code> following <code>x + y</code> actually <b>applies to an inner expression</b>, so instead of calling outer function — and assigning returned value to <code>f2</code> &#8212; <code>f2</code> is being assigned a function that has <code>x + y(1, 2)</code> as its body. Something to be aware of.</p>
</li>
<li>
<p class="q">How does EC work with ES5 accessor syntax (let&#8217;s try getter first)?</p>
<p>Works!</p>
<pre lang="javascript"><code>
var obj = ({ get foo() 1 });
obj.foo; // 1
</code></pre>
</li>
<li>
<p class="q">How about setter?</p>
<p>Works!</p>
<pre lang="javascript"><code>
var _x;
var obj = ({ set foo(x) _x = x });
obj.foo = 5;

_x; // 5
</code></pre>
</li>
<li>
<p class="q">How about both?</p>
<p>Works as well! Well, why wouldn&#8217;t it&#8230;</p>
<pre lang="javascript"><code>
  var _x = 'initial value';
  var obj = ({ get foo() _x, set foo(x) _x = x });
  obj.foo; // 'initial value'

  obj.foo = 'overwritten value';
  obj.foo; // 'overwritten value'
</code></pre>
</li>
<li>
<p class="q">Can we confuse parser with a comma?</p>
<p>Yes we can.</p>
<pre lang="javascript"><code>
  ({ set foo(x) bar = 1, baz = 2 }); // SyntaxError
</code></pre>
<p>In this case, we might want <code>bar = 1, baz = 2</code> as an expression inside a function, but instead, <b>comma is parsed as part of an object intializer</b>. Wrapping expression in parenthesis would solve this problem, of course.</p>
<pre lang="javascript"><code>
  ({ set foo(x) (bar = 1, baz = 2) });
</code></pre>
</li>
<li>
<p class="q">Are statements allowed in function body of a function created via EC?</p>
<p>No.</p>
<pre lang="javascript"><code>
  var f = function() if (true) "foo"; // Error
</code></pre>
<p>This is pretty understandable, considering that expression after <code>function()</code> in EC is treated as an expression inside <code>return</code> statement. And <code>return</code> statement obviously can&#8217;t contain other statements (only expressions). Fortunately, there&#8217;s always a ternary operator to take care of cases like this:</p>
<pre lang="javascript"><code>
  var f = function() someCondition ? "foo" : "bar";
</code></pre>
</li>
<li>
<p class="q">Can body of a function created via EC be omitted?</p>
<p>Nope.</p>
<pre lang="javascript"><code>
  function f() // Error
</code></pre>
<p>You would think that <code>function f()</code> should be identical to <code>function f(){ return }</code>, but no, empty function body is not allowed there. It&#8217;s not clear why this was made like this. Parsing complexities, perhaps?</p>
</li>
<li>
<p class="q">What happens when we include more than 1 expression?</p>
<p>Only first one is consumed.</p>
<pre lang="javascript"><code>
  function f() alert("1st statement"); alert("2nd statement"); // alerts "2nd statement"
</code></pre>
</li>
<p>The above is parsed as <code>function f() alert("1st statement");</code> followed by <code>alert("2nd statement")</code>. Only first expression becomes an expression in the return statement of a function.</p>
<li>
<p class="q">What about automatic semicolon insertion rules?</p>
<p>Same rules seem to apply.</p>
<pre lang="javascript"><code>
  function foo(x) x
  (function() {
    /* ... */
  })()

  foo; // function foo(x) x(function(){ /* ... */})()
</code></pre>
<p>A classic example of ASI — function declaration followed by newline and another expression makes for an unexpected behavior. Same rules apply here, and <code>foo</code> function — even though expressed via EC — ends up having function body of <code>x(function(){})()</code> (rather than just <code>x</code>).</p>
</li>
<li>
<p class="q">Is &#8220;{&#8221; interpreted as a block or an object literal?</p>
<p>As a block! Overall production essentially <b>matches regular function syntax</b>.</p>
<pre lang="javascript"><code>
  function foo(x) { top: 0, left: 0 } // SyntaxError
</code></pre>
<p>You would think that <code>function() { &#8230; }</code> is interpreted as <code>function(){ return { &#8230; } }</code> but the production rules of &#8220;regular&#8221; function syntax precede here, and <code>function foo() { top: 0, left: 0 }</code> results in an error. <code>{</code> and <code>}</code> are essentially parsed as a function body (and <code>top: 0, left: 0</code> as function body contents).</p>
</li>
<li>
<p class="q">What if it&#8217;s an expression?</p>
<p>Same thing. Treated as regular function syntax.</p>
<pre lang="javascript"><code>
  (function(x, y) { left: x, top: y }) // SyntaxError
</code></pre>
<p>
    You need to be careful to wrap returning object with parenthesis, so that curly braces aren&#8217;t considered to be part of a function production. In this case — <code>left: x, top: y</code> results in an error. But if returned object only contains one value, or no value at all, the silent behavior can make for an unexpected behavior down the road:
  </p>
<pre lang="javascript"><code>
  (function() { x: 1 } )(); // returns `undefined`
  (function() ({ x: 1 }) )(); // Expression Closure; returns object with x=1

  (function() {} )(); // returns `undefined`
  (function() ({}) )(); // Expression Closure; returns object
</code></pre>
</li>
<li>
<p class="q">Can we make function explicitly strict?</p>
<p>No.</p>
<pre lang="javascript"><code>
  function foo(x, y) "use strict"; 1 + 1;
  typeof foo(); // "string" (not "number")
</code></pre>
<p>This obviously doesn&#8217;t work; &#8220;use strict&#8221; — which is a strict directive that&#8217;s supposed to make function behave as per ES5 strict mode rules — doesn&#8217;t behave in any special way. It&#8217;s simply treated as a string literal and so resulting function becomes identical to <code>function foo(){ return &#8220;use strict&#8221;; }</code> (followed by a useless <code>1 + 1</code> statement).</p>
</li>
</ol>
<p>(<a href="http://kangax.github.com/jstests/expression_closures_test/">This file</a> was used for testing)</p>
<h3 id="main_features">Main features</h3>
<p>Well that was fun. To summarize some of the main traits:</p>
<ol id="expression-closure-traits">
<li>Function body should always be present</li>
<li>Only first expression is consumed by an implicit return statement</li>
<li>Can be used in place of both — function declaration and function expression (named or anonymous)</li>
<li><code>function id<sub>opt</sub> (args<sub>opt</sub>) expr</code> is <strong>not fully identical</strong> to <code>function id<sub>opt</sub> (args<sub>opt</sub>) { return expr }</code> (depends on context)</li>
<li>Precedence of call expression can be not obvious. For example: <code>(function()x+y)()</code> vs. <code>function()x+y()</code></li>
</ol>
<h3 id="practical">Practical?</h3>
<p>To my knowledge, expression closures are currently only supported by Mozilla-based browsers. They also aren&#8217;t supported by tools like Google Closure Compiler or YUI Compressor, which certainly makes it challenging to use them in production.</p>
<p>It&#8217;s not clear if more implementations will join Mozilla and add support for these shortcuts. Could they be part of an experimental <a href="http://www.aminutewithbrendan.com/pages/20110110">road to Harmony</a> (and its <a href="http://wiki.ecmascript.org/doku.php?id=strawman:shorter_function_syntax">shorter function syntax</a>) — the next version of the ECMAScript language? Do you already use expression closures in your work/experiments, or perhaps planning to? And would you change anything in their behavior?</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerfectionKills?a=-VCPXGm7V0Q:ANe4h4ZVJOY:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerfectionKills?i=-VCPXGm7V0Q:ANe4h4ZVJOY:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerfectionKills/~4/-VCPXGm7V0Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/a-closer-look-at-expression-closures/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://perfectionkills.com/a-closer-look-at-expression-closures/</feedburner:origLink></item>
		<item>
		<title>Global eval. What are the options?</title>
		<link>http://feedproxy.google.com/~r/PerfectionKills/~3/-gjFqUtRmvU/</link>
		<comments>http://perfectionkills.com/global-eval-what-are-the-options/#comments</comments>
		<pubDate>Wed, 15 Dec 2010 19:07:07 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[ECMA-262]]></category>
		<category><![CDATA[ES5]]></category>
		<category><![CDATA[eval]]></category>
		<category><![CDATA[strict-mode]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=334</guid>
		<description><![CDATA[#global-eval-what-are-the-options ul { margin-top: 0; margin-bottom: 0; margin-left: 1em; } #global-eval-what-are-the-options ul li { margin-bottom: 3px; } #global-eval-what-are-the-options .toc { margin-bottom: 30px; } #global-eval-what-are-the-options blockquote p { margin-bottom: 0; } #global-eval-what-are-the-options h5 { font: bold 1.2em Georgia, serif; margin-bottom: 1em; } #global-eval-what-are-the-options .one-liner-downsides { margin-bottom: 20px; } How eval works Eval&#8217;ing in global scope Indirect [...]]]></description>
			<content:encoded><![CDATA[<div id="global-eval-what-are-the-options">
<style>
    #global-eval-what-are-the-options ul { margin-top: 0; margin-bottom: 0; margin-left: 1em; }
    #global-eval-what-are-the-options ul li { margin-bottom: 3px; }
    #global-eval-what-are-the-options .toc { margin-bottom: 30px; }
    #global-eval-what-are-the-options blockquote p { margin-bottom: 0; }
    #global-eval-what-are-the-options h5 { font: bold 1.2em Georgia, serif; margin-bottom: 1em; }
    #global-eval-what-are-the-options .one-liner-downsides { margin-bottom: 20px; }
  </style>
<ul class="toc">
<li><a href="#how_eval_works">How eval works</a></li>
<li>
      <a href="#evaling_in_global_scope">Eval&#8217;ing in global scope</a>
<ul>
<li><a href="#indirect_eval_call_theory">Indirect eval call. Theory.</a>
<ul>
<li><a href="#indirect_eval_call_examples">Indirect eval call examples.</a></li>
</ul>
</li>
<li><a href="#indirect_eval_call_in_practice">Indirect eval call. In practice.</a></li>
<li><a href="#windowexecscript">window.execScript</a></li>
<li><a href="#windoweval">window.eval</a>
<ul>
<li><a href="#eval_context_in_webkit">eval context in webkit</a></li>
</ul>
</li>
<li><a href="#new_function">new Function</a></li>
<li><a href="#settimeout">setTimeout</a></li>
<li><a href="#script_insertion">Script insertion</a></li>
</ul>
</li>
<li><a href="#the_problem_with_geval_windowexecscript_eval">The problem with `window.execScript || eval`</a></li>
<li><a href="#feature_testing_based_approach">Feature testing -based approach</a></li>
<li><a href="#global_eval_in_libraries">Global eval in libraries</a></li>
<li><a href="#summary">Summary</a></li>
</ul>
<p><a href="http://www.davidflanagan.com/">David Flanagan</a> recently <a href="http://www.davidflanagan.com/2010/12/global-eval-in.html">wrote about global eval() in Javascript</a>, proposing a simple one-liner like this:</p>
<pre lang="javascript"><code>
  var geval = this.execScript || eval;
</code></pre>
<p>Even though it looked beautifully simple, it wasn&#8217;t the best cross-browser solution I could think of. Moreover, it&#8217;s not something I would recommend. Pondering a bit more on this subject, I realized that there are actually quite a few ways to evaluate code in global scope in Javascript. Some of those ways — e.g. indirect eval — are also not understood very well, and their implications are not immediately visible. David pointed out to me — in one of the comments — that &#8220;indirect eval&#8221; is not a well-known idiom except in close circles of implementors. And he was right. There was in fact tons of confusion on the subject of global eval, all over the web.</p>
<p>In hope of making the situation clearer, I&#8217;d like to go over &#8220;global eval&#8221; options, taking a look at how and why they work. I&#8217;ll also explain some of the problems with the above-mentioned one-line solution.</p>
<h3 id="how_eval_works">How eval works</h3>
<p>Before going further, let&#8217;s define &#8220;global eval&#8221; as a way to evaluate code in global scope. Simple as that.</p>
<p>The reason for all this fuss about evaluating code in global scope is because global, built-in <code>eval</code> function <strong>evaluates code in the scope of a caller</strong>:</p>
<pre lang="javascript"><code>
  var x = 'outer';
  (function() {
    var x = 'inner';
    eval('x'); // "inner"
  })();
</code></pre>
<p>This behavior is described very clearly in both — ES3 and ES5:</p>
<blockquote><p>
[...]<br />
The scope chain is initialised to contain the same objects, in the same order, as the calling context&#8217;s scope chain. This includes objects added to the calling context&#8217;s scope chain by with statements and catch clauses.<br />
[...]
</p></blockquote>
<p>&#8212; <a href="http://bclary.com/2004/11/07/#a-10.2.2">10.2.2 Eval Code</a> [ES3]</p>
<p>In ES5, things are a bit more <del>complicated</del> interesting. The behavior of <code>eval</code> depends on 2 things — whether it is a <strong>direct or indirect call</strong> and whether <strong>invocation happens in strict mode</strong>. Don&#8217;t worry if you don&#8217;t know what &#8220;indirect call&#8221; is — we&#8217;ll take a look at it very soon. When talking about non-strict, direct eval call (i.e. good old <code>eval(...)</code> invocation) the outcome is exactly the same as in ES3 — code is executed in the scope of a caller.</p>
<blockquote><p>
[...]<br />
b. Set the LexicalEnvironment to the same value as the LexicalEnvironment of the calling execution context.<br />
[...]
</p></blockquote>
<p>&#8212; <a href="http://ecma262-5.com/ELS5_HTML.htm#Section_10.4.2">10.4.2 Entering Eval Code</a> [ES5]</p>
<h3 id="evaling_in_global_scope">Eval&#8217;ing in global scope</h3>
<p>So native <code>eval</code> doesn&#8217;t allow to execute code globally. What to do? Let&#8217;s first take a look at some of the options, then try to distill them into a cross-browser solution.</p>
<h4 id="indirect_eval_call_theory">Indirect eval call. Theory.</h4>
<p>I mentioned &#8220;indirect eval call&#8221; before, when explaining behavior of <code>eval</code> in ES5. The reason indirect eval is of interest is because in ES5 it actually <strong>does execute code globally</strong>. <a href="http://www.youtube.com/watch?v=EDkQZVJshgc">Bingo!</a> But what does it even mean — &#8220;indirect eval call&#8221;. Indirect eval call is simply any eval call that&#8217;s not a direct eval call. And direct eval call is defined as:</p>
<blockquote><p>
A direct call to the eval function is one that is expressed as a CallExpression that meets the following two conditions:<br />
<br />
The Reference that is the result of evaluating the MemberExpression in the CallExpression has an environment record as its base value and its reference name is &#8220;eval&#8221;.<br />
<br />
The result of calling the abstract operation GetValue with that Reference as the argument is the standard builtin function defined in 15.1.2.1.
</p></blockquote>
<p>&#8212; <a href="http://ecma262-5.com/ELS5_HTML.htm#Section_15.1.2.1.1">15.1.2.1.1 Direct Call to Eval</a> [ES5]</p>
<p>That might sound a bit cryptic, but it&#8217;s actually very simple. What specification is trying to tell is that <code>eval('1+1')</code> is a direct call, but <code>(1,eval)('1+1')</code> is not. If we were to dissect first expression — <code>eval('1+1')</code> — syntactically, we would see that it&#8217;s really just a CallExpression, which consists of a MemberExpression (<code>eval</code>) followed by Arguments (<code>'(1+1)'</code>), and in which MemberExpression consists of &#8220;eval&#8221; Identifier:</p>
<pre lang="javascript"><code>
    eval             ( '1+1' )
  |______|
  Identifier

  |______|          |________|
  MemberExpression  Arguments

  |__________________________|
  CallExpression
</code></pre>
<p>This is, more or less, a signature of a direct call. ES3 has a slightly simpler definition, and the one that&#8217;s pretty much identical to the graphic above:</p>
<blockquote><p>
    &#8220;[&#8230;] any way other than a direct call (that is, other than by the <strong>explicit use of its name as an Identifier which is the MemberExpression in a CallExpression</strong>) [&#8230;]&#8221;
  </p></blockquote>
<p>&#8212; <a href="http://bclary.com/2004/11/07/#a-15.1.2.1">15.1.2.1 eval(x)</a> [ES3]</p>
<p>So <code>eval('1+1')</code> is a direct eval call, but (1,eval)(&#8216;1+1&#8217;) is not. Since the latter one is not a direct call, it is therefore an <strong>indirect eval call</strong>. Let&#8217;s take a look at it in more detail:</p>
<pre lang="javascript"><code>
  (     1        ,         eval  )        ( '1+1' )
     |____|   |_____|    |_____|
     Literal  Operator   Identifier

     |_________________________|
     Expression

  |______________________________|
  PrimaryExpression

  |______________________________|        |________|
  MemberExpression                        Arguments

  |________________________________________________|
  CallExpression
</code></pre>
<p>In the above example, the part before Arguments (invocation parens) clearly doesn&#8217;t consist of just &#8220;eval&#8221; identifier. There&#8217;s a whole other expression, consisting of comma operator, numeric literal, and only then &#8220;eval&#8221; identifier. <code>1,eval</code> — based on how comma operator works — still evaluates to a standard, built-in <code>eval</code> function, but overall expression is no longer a direct call. It is therefore an <strong>indirect eval call</strong>.</p>
<h5 id="indirect_eval_call_examples">Indirect eval call examples</h5>
<p>If you&#8217;re still not quite able to recognize indirect eval calls, these are some of the examples:</p>
<pre lang="javascript"><code>
(1, eval)('...')
(eval, eval)('...')
(1 ? eval : 0)('...')
(__ = eval)('...')
var e = eval; e('...')
(function(e) { e('...') })(eval)
(function(e) { return e })(eval)('...')
(function() { arguments[0]('...') })(eval)
this.eval('...')
this['eval']('...')
[eval][0]('...')
eval.call(this, '...')
eval('eval')('...')
</code></pre>
<p>According to ES5, all of these are indirect calls and <strong>should execute code in global scope</strong>. I&#8217;d love to go over each one of them in more detail, but that would be too much for this post.</p>
<p>Note the <code>var e = eval; e('...')</code> on 5th line. </p>
<p>You can see that this is essentially what David&#8217;s solution does — <code>var geval = window.execScript || eval</code>. When <code>geval</code> is executed, <code>geval</code> identifier resolves to a global, built-in <code>eval</code> function, but overall expression does not have &#8220;eval&#8221; as an Identifier in CallExpression. Instead, there&#8217;s &#8220;geval&#8221; identifier, <strong>making this an indirect call</strong> and evaluating code globally.</p>
<p>But we&#8217;ll get back to that one-liner later, and now let&#8217;s take a look at one last, but not least important point about indirect eval call.</p>
<p>Have you noticed how ES5 definition says that <code>eval</code> from CallExpression <strong>should evaluate to standard, built-in function</strong>? It means that taken out of context, <code>eval('1+1')</code> is <strong>not necessarily a direct call</strong>. Only when <code>eval</code> actually references standard, built-in function (wasn&#8217;t overwritten or shadowed), a call can be considered direct.</p>
<pre lang="javascript"><code>
  eval = (function(eval) {
    return function(expr) {
      return eval(expr);
    };
  })(eval);

  eval('1+1'); // It looks like a direct call, but really is an indirect one.
               // It's because `eval` resolves to a custom function, rather than standard, built-in one
</code></pre>
<p>Now that we looked at a list of indirect calls, how about few examples of <strong>direct ones</strong>?</p>
<pre lang="javascript"><code>
  eval('...')
  (eval)('...')
  (((eval)))('...')
  (function() { return eval('...') })()
  eval('eval("...")')
  (function(eval) { return eval('...'); })(eval)
  with({ eval: eval }) eval('...')
  with(window) eval('...')
</code></pre>
<p>Looks pretty straightforward, doesn&#8217;t it?</p>
<p>But wait a second. Why is it that <code>(eval)('...')</code> and <code>(((eval)))('...')</code> are considered direct calls? Certainly, they don&#8217;t adhere to the signature we established earlier — Identifier &#8220;eval&#8221; within MemberExpression within CallExpression. What&#8217;s going on here? Shouldn&#8217;t the <strong>parenthesis around <code>eval</code></strong> make it an indirect call?</p>
<p>The answer to this tricky question is in the first paragraph of ES5 direct call definition — the fact that &#8220;eval&#8221; in CallExpression <strong>should be a Reference, not a value</strong>. During program execution, <code>eval</code> in <code>eval('1+1')</code> expression is nothing but a Reference, and needs to be evaluated to a value. Once it&#8217;s evaluated, the value is (most likely) a standard, built-in function object. What happens in previously dissected <code>(1,eval)('1+1')</code> indirect call, is that <code>(1,eval)</code> expression evaluates to a value, not a Reference. Since it doesn&#8217;t evaluate to a Reference, it can not be considered a direct eval call. </p>
<p>But what about <code>(eval)('1+1')</code>?</p>
<p>The reason <code>(eval)</code> is considered a direct eval call is because <code>(eval)</code> expression <strong>still evaluates to a Reference</strong>, not a value. Ditto for <code>((eval))</code>, <code>(((eval)))</code>, and so on. This happens because Grouping Operator — &#8220;(&#8221; and &#8220;)&#8221; — <strong>does not evaluate its expression</strong>. If a Reference is passed to a Grouping operator — &#8220;(&#8221; and &#8220;)&#8221; — it still evaluates to a Reference, not a value.</p>
<pre lang="javascript"><code>
  eval(); // <-- expression to the left of invocation parens — "eval" — evaluates to a Reference
  (eval)(); // <-- expression to the left of invocation parens — "(eval)" — evaluates to a Reference
  (((eval)))(); // <-- expression to the left of invocation parens — "(((eval)))" — evaluates to a Reference
  (1,eval)(); // <-- expression to the left of invocation parens — "(1, eval)" — evaluates to a value
  (eval = eval)(); // <-- expression to the left of invocation parens — "(eval = eval)" — evaluates to a value
</code></pre>
<p>Speaking in terms of ECMAScript, this is because both — comma operator (in <code>(1, eval)</code> example) and <code>=</code> operator (in <code>(eval = eval)</code> example) perform <code>GetValue</code> on its operands. As a result, <code>(1, eval)</code> and <code>(eval = eval)</code> evaluate to a value, whereas <code>eval</code> and <code>(eval)</code> — to a Reference.</p>
<p>Hopefully, it is now clear why <code>(eval)('...')</code> and <code>(function(eval){ return eval('...') })(eval)</code> are direct eval calls, but <code>(1, eval)('...')</code> and <code>this.eval('...')</code> aren&#8217;t.</p>
<h4 id="indirect_eval_call_in_practice">Indirect eval call. In practice.</h4>
<p>With all the theory of indirect <code>eval</code> behind us, let&#8217;s consider practical implications. We already know that ES5 specifies such calls to evaluate code in global scope. There are only 2 things left to consider — ES3 and reality. The fun part starts with ES3, which <a href="http://bclary.com/2004/11/07/#a-15.1.2.1">allows indirect eval calls to throw an error</a>. Not only does ES3 allow for an error, it says nothing about evaluating code in global scope. And what about reality? </p>
<p>It turns out that quite a lot of environments nowadays more or less <a href="http://kangax.github.com/jstests/indirect_eval_call_test/">follow ES5 behavior</a>, evaluating code in global scope. But unfortunately, not all of them. </p>
<p>IE&lt;=8 executes code in the scope of a caller, as if indirect call was direct one. Some versions of Konqueror (~4.3) and Safari &lt;=3.2 do the same thing as IE, evaluating code in the scope of a caller. Older Opera (~9.27) goes even further and actually does throw error, as permitted by a spec. All of this makes indirect <code>eval</code> call (on its own) not a good candidate for a cross-browser &#8220;global eval&#8221; solution. Not for another few years (when Opera &lt;=9.27, Safari &lt;=3.2 (which is probably still present in earlier iPhones), and other &#8220;misbehaving&#8221; browsers &#8220;disappear&#8221;).</p>
<p>Curiously, as of now, even the newest browsers deviate from ES5. Chrome 9, for example, considers this an indirect call — <code>(function(eval){ return eval('x'); })(eval)</code> — which it really isn&#8217;t; <code>eval</code> is a reference, it&#8217;s part of a MemberExpression within a CallExpression, and evaluates to a standard, built-in function.</p>
<p>Opera 11 and Firefox 4 — both browsers are still in beta for these versions — consider the following expression to be a direct call, even though it doesn&#8217;t satisfy all requirements of such (<code>eval</code> doesn&#8217;t resolve to a standard, built-in function in this case):</p>
<pre lang="javascript"><code>
  eval = (function(eval) {
    return function(s) {
      return eval(s)
    };
  })(eval);

  eval('...');
</code></pre>
<p>Full ES5 conformance is clearly yet to come (meanwhile, take a look at <a href="http://kangax.github.com/jstests/indirect-eval-testsuite/">my simple test suite</a>).</p>
<h4 id="windowexecscript">window.execScript</h4>
<p>Fortunately for us, there&#8217;s a proprietary <a href="http://msdn.microsoft.com/en-us/library/ms536420(v=VS.85).aspx"><code>window.execScript</code></a> function present in IE. It&#8217;s defined to &#8220;execute the specified script in the provided language&#8221; and allows to execute Javascript code in global scope. It&#8217;s not very surprising that Chrome has this function as well; most likely for compatibility reasons. As of today, <code>window.execScript</code> is still present in Chrome 9. </p>
<p>The way <code>window.execScript</code> differs from indirect eval call is that it <strong>doesn&#8217;t return a value</strong>. Actually, it does return value in Chrome, but that value is always <code>null</code>. </p>
<pre lang="javascript"><code>
  window.execScript('1+1'); // null in Chrome, undefined in IE
  (1,eval)('1+1'); // 2
</code></pre>
<h4 id="windoweval">window.eval</h4>
<p>Another, very popular way to execute code in global scope is using <code>window.eval</code>. What&#8217;s interesting about it, is that <code>window.eval('...')</code> is <strong>often believed to be somehow special</strong> when it comes to executing code globally. It&#8217;s as if <code>eval</code> called as a property of <code>window</code> object always executes in global scope. The truth is that <code>window.eval('...')</code> is nothing but a&#8230; <strong>indirect eval call</strong>, and is not much different than (1,eval)(&#8216;&#8230;&#8217;), <code>this.eval('...')</code>, or <code>(eval = eval)('...')</code> when it comes to evaluation. </p>
<p>Not understanding what&#8217;s going on, some people unfortunately <a href="http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context">come up with rather monstrous solutions</a> like <code>eval.call(window, '...')</code>,  <code>window.eval.call(window, '...')</code> and even scarier combinations. All of those are, once again, nothing but indirect eval calls. The reason code is executed in global scope is not because <code>eval</code> is called in context of <code>window</code>, but because <strong>it&#8217;s invoked as an indirect call</strong>. <code>eval</code> might as well be a property of <code>foo</code> object, and would still work identically:</p>
<pre lang="javascript"><code>
  var foo = {
    eval: eval
  };

  foo.eval('...'); // behaviorally identical to `window.eval('...')`
                   // both are indirect calls and so evaluate code in global scope
</code></pre>
<p>More <a href="http://stackoverflow.com/questions/2566973/how-override-eval-function-in-javascript">confusion can be seen on StackOverflow</a>, where <code>eval</code> is labeled &#8220;magic&#8221;, and is claimed to somehow lose its magic when aliased — all the <strong>symptoms of direct vs. indirect calls</strong>.</p>
<h5 id="eval_context_in_webkit">eval context in webkit</h5>
<p>It&#8217;s worth mentioning that in some of the WebKit -based browsers — including latest Safari (5) and Chrome (9) — <strong><code>eval</code> throws error</strong> when called from within certain context (a.k.a. &#8220;this&#8221; object). And by &#8220;certain context&#8221; I mean anything that&#8217;s not a window/global object (or at least it seems that way). The error is <cite>EvalError: The &#8220;this&#8221; object passed to eval must be the global object from which eval originated</cite>. This is probably done for security reasons.</p>
<pre lang="javascript"><code>
  window.eval('1+1'); // works
  eval.call(window, '1+1'); // works
  eval.call(null, '1+1'); // works, since eval is invoked with "this" object referencing global object

  eval.call({ }, '1+1'); // EvalError (wrong "this" object)
  [eval][0]('1+1'); // EvalError (wrong "this" object)
  with({ eval: eval }) eval('1+1'); // EvalError (wrong "this" object)
</code></pre>
<p>Since all of those calls are indirect ones, such error is allowed by ES3 (see, for example, EvalError — <a href="http://bclary.com/2004/11/07/#a-15.11.6.1">15.11.6.1</a>)</p>
<h4 id="new_function">new Function</h4>
<p>Sometimes I see suggestions to use <code>new Function</code> (or just <code>Function</code>) to evaluate code globally:</p>
<pre lang="javascript"><code>
  Function('return 1+1')(); // 2
</code></pre>
<p>This is somewhat misleading.</p>
<p>The code executed from within function created by <code>Function</code> constructor doesn&#8217;t really execute in global scope. However, it doesn&#8217;t execute in local scope either, which is what probably leads to confusion. <code>Function</code> constructor creates a function whose scope chain consists of nothing but a global scope (preceded with function&#8217;s own Activation Object, of course). Any code contained in a function created via <code>Function</code> constructor <strong>evaluates in a scope of that function, not in a global scope</strong>. However, it&#8217;s <em>almost as if</em> code executes globally, since global object is the very next object in the scope chain.</p>
<p>What are the implications of this difference?</p>
<p>Well, for once, any function/variable declarations are performed using created function&#8217;s Activation Object as Variable Object. In other words, they are declared local to created function, rather than in a global scope:</p>
<pre lang="javascript"><code>
  function globalEval(expression) {
    return Function(expression)();
  }

  var x = 'outer';
  (function() {
    var x = 'inner';
    globalEval('alert(x)'); // alerts "outer"
  })();

  // but!

  globalEval('var foo = 1');
  typeof foo; // "undefined" (`foo` was declared within function created by `Function`, not in the global scope)
</code></pre>
<p>Another interesting peculiarity of evaluating code via <code>Function('...')()</code> is <strong>identifiers leakage</strong>. An example of this is "arguments" identifier which resolves to an <code>arguments</code> object, when evaluating code via <code>Function('...')()</code>:</p>
<pre lang="javascript"><code>
  eval('alert(arguments)'); // ReferenceError
  Function('alert(arguments)')(); // alerts representation of an `arguments` object
</code></pre>
<p><code>Function</code> -executed code is a good solution if you wish to avoid executing code locally, but it won&#8217;t execute it globally either.</p>
<h4 id="settimeout">setTimeout</h4>
<p>Non-standard (but finally <a href="http://www.whatwg.org/specs/web-apps/current-work/?slow-browser#dom-windowtimers-settimeout">codified in currently draft HTML5</a>) <code>setTimeout</code> is another way to execute code globally — when given code as a string, rather than as a function. The problem with <code>setTimeout</code>, of course, is that it&#8217;s asynchronous and that — similarly to <code>window.execScript</code> — it doesn&#8217;t return the result of evaluation.</p>
<p>Unfortunately, looking through HTML5 specs, I couldn&#8217;t find any mention of the fact that <code>setTimeout</code> should evaluate code in global scope. Hopefully, I missed it; it should certainly be specified.</p>
<h4 id="script_insertion">Script insertion</h4>
<p>Finally, in browser environment, there&#8217;s always an option of injecting a script element into a document. Contents of that script element are then parsed and executed as a Program in global scope:</p>
<pre lang="javascript"><code>
  var el = document.createElement('script');
  el.appendChild(document.createTextNode('1+1'));
  document.body.appendChild(el);
</code></pre>
<p>As with <code>window.execScript</code> and <code>setTimeout</code> -based solutions, this one doesn&#8217;t allow to get meaningful return value (unless some kind of workaround is applied). Script insertion is used by current jQuery (1.4.4) in <code>jQuery.globalEval</code>. It fails to provide a return value, but works in more cross-browser manner than &#8220;indirect eval + window.execScript&#8221; combination. For example, it works in Safari &lt;=3.2 and in older Opera, in which indirect eval calls fail.</p>
<h3 id="the_problem_with_geval_windowexecscript_eval">The problem with <code>window.execScript || eval</code></h3>
<p>Let&#8217;s get back to this very appealing one-liner, taking a look at some of its problems. Although it seems great in theory, its 2 main downsides can be summarized as:</p>
<ul class="one-liner-downsides">
<li>Indirect <code>eval</code> is not sufficiently cross-browser; lack of feature-testing</li>
<li>Non-standard <code>execScript</code> is preferred to standard <code>eval</code></li>
</ul>
<p>As you&#8217;ve seen before, indirect eval is still quirky across some of the existing browsers. There are also environments where it hasn&#8217;t even been tested in — mobile browsers, non-standard platforms, older, rare or unknown browsers, etc. Relying on the fact that indirect eval executes code globally — just because that&#8217;s what happens in some of the newer, popular browsers — is rather careless. A much saner strategy is to actually feature test indirect eval call behavior before attempting to use it.</p>
<p>Another problem of one-liner is that <code>window.execScript</code> is tested for existence first, and only when it doesn&#8217;t exist, <code>eval</code> is chosen as a fallback. One of the rules of interoperability is that <strong>standard features should be preferred over non-standard ones</strong>. For example, since <code>window.execScript</code> exists in Chrome, one-liner will end up &#8220;using&#8221; non-standard (and less-capable) <code>window.execScript</code> rather than standard <code>eval</code>.</p>
<p>Finally, the assumption that if <code>window.execScript</code> doesn&#8217;t exist, then indirect eval must be executing code globally (which is what one-liner does) strikes me as rather unsafe.</p>
<p>There are more <a href="http://josephsmarr.com/2007/01/31/fixing-eval-to-use-global-scope-in-ie/">similarly non-optimal soutions online</a>, where folks seem to be taking trial-and-error approach, not realizing why things work the way they do. Rakesh Pai is <a href="http://blog.rakeshpai.me/2008/10/understanding-eval-scope-spoiler-its.html">bedazzled by the unexplainable difference</a> between <code>eval</code> and <code>window.eval</code> invocations:</p>
<blockquote style="margin-bottom: 20px"><p>
    I don&#8217;t know what Firefox is doing in case 2, and for some reason Safari Nightlies seem to be following it. Maybe it&#8217;s just beyond my understanding, but case 2 is not supposed to be different from case 1. Why does case 2 operate in global scope? If window.eval is different from eval, case 3 shouldn&#8217;t all have given errors. Someone please help me understand that $hit.
  </p></blockquote>
<p>The fact that browsers do not fully conform to ES5 makes things even worse. For example, <code>with(window) eval('...')</code> is considered an indirect call in Chrome 9, even though as per ES5 it is very much a direct one — the &#8220;eval&#8221; Identifier is within MemberExpression of CallExpression; it&#8217;s a Reference, and it resolves to a standard, built-in <code>eval</code> function. </p>
<h3 id="feature_testing_based_approach">Feature testing -based approach</h3>
<p>Creating a more robust version of global eval is not hard. </p>
<p>The idea is similar — use indirect eval, with a fall back on <code>window.execScript</code>. The important difference, however, is that <strong>indirect eval is feature-tested</strong> and is only used when it&#8217;s safe to do so. One potential problem here is that <code>window.execScript</code> is not tested, but is instead assumed to execute code globally. If you find this assumption unsafe, it should be trivial to add feature-test for <code>window.execScript</code> as well.</p>
<pre lang="javascript"><code>
var globalEval = (function() {

  var isIndirectEvalGlobal = (function(original, Object) {
    try {
      // Does `Object` resolve to a local variable, or to a global, built-in `Object`,
      // reference to which we passed as a first argument?
      return (1,eval)('Object') === original;
    }
    catch(err) {
      // if indirect eval errors out (as allowed per ES3), then just bail out with `false`
      return false;
    }
  })(Object, 123);

  if (isIndirectEvalGlobal) {

    // if indirect eval executes code globally, use it
    return function(expression) {
      return (1,eval)(expression);
    };
  }
  else if (typeof window.execScript !== 'undefined') {

    // if `window.execScript exists`, use it
    return function(expression) {
      return window.execScript(expression);
    };
  }

  // otherwise, globalEval is `undefined` since nothing is returned
})();
</code></pre>
<p>The benefit of this kind of implementation is that <strong>it enables graceful degradation</strong>. You can easily find out if <code>globalEval</code> is available in a current environment (since <code>globalEval</code> would be <code>undefined</code> when none of the 2 solutions are available):</p>
<pre lang="javascript"><code>
  if (globalEval) {
    /* code can be executed globally */
  }
  else {
    /* use fallback scenario */
  }
</code></pre>
<p>Note that — as with any indirect eval / <code>window.execScript</code> approach — <code>globalEval</code> will differ in its ability to return a value, depending on which method was chosen.</p>
<h3 id="global_eval_in_libraries">Global eval in libraries</h3>
<p>So what do some of the popular Javascript libraries do? Which global eval solution do they chose?</p>
<p>As we&#8217;ve seen earlier, <strong>jQuery</strong> sacrifices return value for a more extensive browser support, using script insertion technique in its <code>jQuery.globalEval</code> method. </p>
<p><strong>Prototype.js</strong> doesn&#8217;t even try to evaluate scripts globally — it uses a good old, direct eval invocation. Instead, Prototype.js warns about ramification of local execution in the documentation. </p>
<p><strong>Dojo</strong> choses the infamous <code>window.eval</code> variation, but does something really messed up — it uses indirect eval if <code>eval</code> exists on a global object (which should be true in all ES3-compliant browsers), and falls back on regular eval invocation. This kind of fall back obviously results in code executed locally, which should also happen <em>silently</em>. Dojo&#8217;s <code>eval</code> behavior will vary wildly depending on the environment, and has a possibility of uncaught error. On a related, humorous note, I was just as stunned by comments around <code>dojo.eval</code> as <a href="http://mail.dojotoolkit.org/pipermail/dojo-interest/2010-February/043637.html">David Mark in this message</a>.</p>
<p><strong>Mootools</strong> uses <code>window.execScript</code> when present, falling back on script insertion (similar to jQuery). jQuery&#8217;s script insertion, however, is more robust than Mootools, as they actually test if it results in evaluation of code.</p>
<p><strong>Fuse.js</strong> choses a very elaborate and careful strategy. It tests if indirect eval works as expected (catching an error if any), uses it if it does; if indirect eval is defunct, Fuse falls back on script injection. Unlike jQuery or Mootools, it actually <strong>tries to return a value</strong> of a code executed via script injection. It does so by wrapping contents of code with eval. An interesting side effect of executing code globally via <code>eval</code> is that function and variable declarations <a href="http://perfectionkills.com/understanding-delete/#firebug_confusion">create <strong>deletable bindings</strong></a> (which is most likely an insignificant detail).</p>
<h3 id="summary">Summary</h3>
<p>So what can we learn from all this? </p>
<p>Hopefully, you now have a true understanding of why <code>eval</code> sometimes executes code in global scope. That <code>window.eval(...)</code> is not very special and is just another form of indirect eval. That behavior of indirect eval is specified differently in ES3 and ES5. That behavior of indirect eval in actual implementations is still often sporadic — partly due to transitioning from ES3 to ES5, partly because of uncaught bugs. You&#8217;ve seen that blindly relying on indirect eval is unsafe. That implementations of &#8220;global eval&#8221; relying on indirect eval should employ feature testing, as with so many other things in cross-browser scripting. Finally, that alternative techniques exist and are used by libraries, such as script injection.</p>
</div>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerfectionKills?a=-gjFqUtRmvU:DxWDeYZm2dk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerfectionKills?i=-gjFqUtRmvU:DxWDeYZm2dk:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerfectionKills/~4/-gjFqUtRmvU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/global-eval-what-are-the-options/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		<feedburner:origLink>http://perfectionkills.com/global-eval-what-are-the-options/</feedburner:origLink></item>
		<item>
		<title>How ECMAScript 5 still does not allow to subclass an array</title>
		<link>http://feedproxy.google.com/~r/PerfectionKills/~3/-VkH0LKhxI8/</link>
		<comments>http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 16:07:38 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[ECMA-262]]></category>
		<category><![CDATA[ES5]]></category>
		<category><![CDATA[iframes]]></category>
		<category><![CDATA[isArray]]></category>
		<category><![CDATA[[[Class]]]]></category>
		<category><![CDATA[[[Construct]]]]></category>
		<category><![CDATA[[[Prototype]]]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=277</guid>
		<description><![CDATA[.subclassing-array .yes, table .no { text-align: center; } .subclassing-array .yes { background-color: #afa; } .subclassing-array .no { background-color: #faa; } .subclassing-array thead th { padding: 0.5em 1em; } .subclassing-array tbody th { padding-right: 1em; text-align: left; } .subclassing-array h4 { font-size: 1em; } .subclassing-array table { margin-bottom: 2em; } .subclassing-array ul li { margin-bottom: 0.25em; [...]]]></description>
			<content:encoded><![CDATA[<div class="subclassing-array">
<style>
    .subclassing-array .yes, table .no { text-align: center; }
    .subclassing-array .yes { background-color: #afa; }
    .subclassing-array .no { background-color: #faa; }
    .subclassing-array thead th { padding: 0.5em 1em; }
    .subclassing-array tbody th { padding-right: 1em; text-align: left; }
    .subclassing-array h4 { font-size: 1em; }
    .subclassing-array table { margin-bottom: 2em; }
    .subclassing-array ul li { margin-bottom: 0.25em; }
    .subclassing-array ul { margin-left: 0; }
  </style>
<ul>
<li><a href="#why_subclass_an_array">Why subclass an array?</a></li>
<li><a href="#naive_approach">Naive approach</a></li>
<li><a href="#problems_with_naive_approach">Problems with naive approach</a></li>
<li><a href="#special_nature_of_arrays">Special nature of arrays</a></li>
<li><a href="#function_objects_and_construct">Function objects and [[Construct]]</a></li>
<li><a href="#the_importance_of_array_special_behavior">The importance of array special behavior</a></li>
<li><a href="#existing_solutions">Existing solutions</a></li>
<li><a href="#ecmascript_5_accessors_to_the_rescue">ECMAScript 5 accessors to the rescue</a></li>
<li><a href="#class_limitations">[[Class]] limitations</a></li>
<li><a href="#does_class_matter">Does [[Class]] matter?</a></li>
<li><a href="#wrappers_direct_property_injection">Wrappers. Direct property injection.</a></li>
<li><a href="#wrappers_prototype_chain_injection">Wrappers. Prototype chain injection.</a></li>
<li><a href="#summary">Summary</a></li>
</ul>
<p>Subclassing an array in Javascript has never been a trivial task. At least for a certain meaning of &#8220;subclassing an array&#8221;. Curiously, new edition of the language — ECMAScript 5 — still <strong>does not allow to fully subclass an array</strong>.</p>
<p>Not everything is lost though, and there are few ways ECMAScript 5 makes this task closer to the ideal. However, there are few <strong>fundamental issues</strong> which prevent true array subclassing from happening.</p>
<p>Let&#8217;s talk about that.</p>
<p>Today we&#8217;ll take a look at what it means to subclass an array, what some of the existing implementations/workarounds are, and which drawbacks those implementations have; We&#8217;ll see what ECMAScript 5 brings to the table, and what those fundamental issues with subclassing are. We&#8217;ll also talk about alternative approaches to subclassing an array, such as using wrappers, and get to know their limitations.</p>
<p>But first, what does it mean to subclass an array? And why do we even need it?</p>
<h3 id="why_subclass_an_array">Why subclass an array?</h3>
<p>We can define &#8220;subclassing an array&#8221; as the process of creating an object which inherits from native <code>Array</code> object (has <code>Array.prototype</code> in its prototype chain), and follows behavior similar (or identical) to native array.</p>
<p>The last point about <strong>behavior similar to native array</strong> is actually very important, as we&#8217;ll see later on. Having &#8220;subclass&#8221; of array could be thought of as being able to create an array object, but an object which would inherit not directly from <code>Array</code>, but from another object, and only then from <code>Array</code>.</p>
<p>In other words, we want behavior similar to this:</p>
<pre lang="javascript"><code>
var sub = new SubArray(1, 2, 3);
sub; // [1, 2, 3]

sub.length; // 3
sub[1]; // 2

sub.push(4);
sub; // [1, 2, 3, 4]

// etc.

sub intanceof SubArray; // true
sub intanceof Array; // true
</code></pre>
<p>Note how <code>SubArray</code> constructor creates a <code>sub</code> object identical in its behavior to array (object has &#8220;length&#8221; property, numeric &#8220;0&#8221;, &#8220;1&#8221;, &#8220;2&#8221; properties, and inherits <code>Array.prototype.*</code> methods). At the same time, it is <code>SubArray</code> that a <code>sub</code> object <strong>directly inherits from</strong>, not <code>Array</code>.</p>
<p>So what exactly is the purpose of doing all this? Why subclass an array in such way?</p>
<p>There are usually two reasons:</p>
<h4 id="avoid_pollution_of_global_array">1. Avoid pollution of global <code>Array</code></h4>
<p>Javascript prototypal nature makes it easy to extend all array objects with custom methods. Instead of assigning to direct properties of array objects, it&#8217;s much easier and more efficient to assign to array&#8217;s &#8220;prototype&#8221; object (the one that&#8217;s usually accessed via <code>Array.prototype</code>). </p>
<pre lang="javascript"><code>
Array.prototype.last = function () {
  return this[this.length-1];
};
// ...
[1, 2, 3].last(); // 3
</code></pre>
<p>However, extending <code>Array.prototype</code> comes with the price; And that price is chance of collisions. When scripts coexist with other scripts in an application, it&#8217;s important for those scripts not to conflict with each other. Extending <code>Array.prototype</code>, while tempting and seemingly useful, unfortunately isn&#8217;t very safe in a diverse environment. Different scripts can end up defining same-named methods, but with different behavior. Such scenario often leads to inconsistent behavior and hard-to-track errors.</p>
<p>Collisions can happen not only with user-defined code, but also with <strong>proprietary methods</strong> implemented by environment itself (e.g. <code>Array.prototype.indexOf</code> from JavaScript 1.6, before it was standardized by <abbr title="ECMAScript 5">ES5</abbr>) or from <strong>future standards</strong> (e.g. <code>Array.prototype.map</code>, <code>Array.prototype.reduce</code>, etc. — now all part of <abbr title="ECMAScript 5">ES5</abbr>).</p>
<p>Using constructor function other than native <code>Array</code> — but with same behavior — would allow to avoid such collisions. Instead of extending <code>Array.prototype</code>, another object would be extended (say, <code>SubArray.prototype</code>) and then used to initialize (sub)array objects. Any third party code which depends on methods from <code>Array.prototype</code> would still be able to safely use them.</p>
<h4 id="create_data_structures_naturally_inheriting_from_array">2. Create data structures naturally inheriting from array</h4>
<p>Another reason to subclass an array is to be able to create data structures, which naturally inherit from array; such as Stack, List, Queue, Set, etc. While there are certainly valid use cases for these structures, in this article I will instead focus on the first aspect — reducing chance of collisions. It is somewhat more relevant in context of cross-browser scripting.</p>
<h3 id="naive_approach">Naive approach</h3>
<p>Creating objects that inherit from other objects is more or less straightforward in Javascript. We can use well-known <code>clone</code> method:</p>
<pre lang="javascript"><code>
function clone(obj) {
  function F() { }
  F.prototype = obj;
  return new F();
}
</code></pre>
<p>and then set-up inheritance like this:</p>
<pre lang="javascript"><code>
function Child() { }
Child.prototype = clone(Parent.prototype);
</code></pre>
<p><code>clone</code> might look confusing, but all it does is create an object with another object as nearest ancestor in its prototype chain. It uses intermediate function to avoid executing &#8220;parent&#8221; constructor. In this example, <code>new Child</code> creates an object with <code>Child.prototype</code> as first object in the prototype chain, <code>Parent.prototype</code> — second, and so on. To visualize, the prototype chain here looks like this:</p>
<pre lang="javascript"><code>
new Child()
    |
    | [[Prototype]]
    |
    v
Child.prototype
    |
    | [[Prototype]]
    |
    v
Parent.prototype
    |
    | [[Prototype]]
    |
    v
Object.prototype
    |
    | [[Prototype]]
    |
    v
   null
</code></pre>
<p>Using <code>clone</code> method is exactly what person attempts when trying to subclass an array for the first time:</p>
<pre lang="javascript"><code>
function SubArray() {
  // Take any arguments passed to constructor and add them to an instance
  this.push.apply(this, arguments);
}
SubArray.prototype = clone(Array.prototype);

var sub = new SubArray(1, 2, 3);
</code></pre>
<p>The approach seems reasonable. After all, the goal is to create an object that inherits from <code>Array</code>, so there&#8217;s no reason tried-and-true <code>clone</code> wouldn&#8217;t work. Or is there? As with few other things in Javascript, it&#8217;s not as trivial as it seems.</p>
<h3 id="problems_with_naive_approach">Problems with naive approach</h3>
<p>So what exactly is wrong with subclassing array using <code>clone</code> method? Let&#8217;s take a look at how previously declared <code>SubArray</code> function behaves. We&#8217;ll be using native array object alongside, for comparison.</p>
<pre lang="javascript"><code>
var arr = new Array(1, 2, 3);
var sub = new SubArray(1, 2, 3);

arr.length; // 3
sub.length; // 0 (in IE<8)

arr.length = 2;
sub.length = 2;

arr; // [1, 2]
sub; // [1, 2, 3]

arr[10] = 'foo';
sub[10] = 'foo';

arr.length; // 11
sub.length; // 2
</code></pre>
<p>There&#8217;s clearly some kind of inconsistency here. Even not counting a bug in IE&lt;8. But what is this strange relation between <code>length</code> and numeric properties in array? And why doesn&#8217;t subclassed array behave identical? To understand this, we need to look into what array objects in Javascript really are.</p>
<h3 id="special_nature_of_arrays">Special nature of arrays</h3>
<p>It turns out that arrays in Javascript are almost like plain <code>Object</code> objects, except for one little difference in behavior. The crux of this difference is summarized concisely in one paragraph of specification (<a href="http://bclary.com/2004/11/07/#a-15.4" title="Chapter 15.4 of ECMA-262, 3rd ed.">15.4</a>):</p>
<p>  <cite style="background: #ffc; padding: 1em; border: 1px solid orange; display: block;">Array objects give special treatment to a certain class of property names. A property name P (in the form of a string value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 2^32 - 1. Every Array object has a length property whose value is always a nonnegative integer less than 2^32. The value of the length property is numerically greater than the name of every property whose name is an array index; whenever a property of an Array object is created or changed, other properties are adjusted as necessary to maintain this invariant. Specifically, whenever a property is added whose name is an array index, the length property is changed, if necessary, to be one more than the numeric value of that array index; and whenever the length property is changed, every property whose name is an array index whose value is not smaller than the new length is automatically deleted. This constraint applies only to properties of the Array object itself and is unaffected by length or array index properties that may be inherited from its prototype.<br />
  </cite></p>
<p>For those allergic to the condensed language of ECMA-262, here&#8217;s a short summary.</p>
<p>Array objects treat &#8220;numeric&#8221; properties in a special way. Whenever such property changes, value of array&#8217;s <strong>&#8220;length&#8221; property is adjusted as well</strong>; it&#8217;s adjusted in such was as to make sure that it is always one more than the greatest numeric (own) property of an array. Similarly, when &#8220;length&#8221; property is changed, <strong>numeric properties are adjusted accordingly</strong> (but only those that are larger than value of &#8220;length&#8221;).</p>
<p>We have already seen relation between numeric properties and length in the previous example, but let&#8217;s take a look at it again, step by step:</p>
<p>1) When array object is created, its &#8220;length&#8221; property is set to a value one more than the largest index of an array.</p>
<pre lang="javascript"><code>
  var arr = ['x', 'y', 'z'];
  arr.length; // 3 (1 greater than largest index of an array — 2 in this case)

  arr = ['foo'];
  arr.length; // 1 (1 greater than largest index of an array — 0 in this case)
</code></pre>
<p>2) When numeric properties change, so does &#8220;length&#8221; change — to maintain the relationship of being 1 greater than the largest index.</p>
<pre lang="javascript"><code>
var arr = ['x', 'y'];
arr.length; // 2, as expected

arr[2] = 'z'; // add another numeric property (2) larger than the largest existing one (1)
arr.length; // 3 — length is changed to be 1 greater than (new) largest index (2)
</code></pre>
<p>3) When &#8220;length&#8221; property changes, numeric properties are adjusted in such way so that greatest index is 1 smaller than value of &#8220;length&#8221;.</p>
<pre lang="javascript"><code>
var arr = ['x', 'y', 'z'];
arr.length = 2;

arr; // ['x', 'y'] — note how last element (z) is deleted, because being at 2nd index,
     //              it doesn't satisfy criteria of largest index being 1 less than length

arr.length = 4;

arr; // ['x', 'y'] — "increasing" length doesn't affect numeric properties...

arr.join(); // "x,y,," ...but has consequences visible in other cases, such as when using `Array.prototype.join`

arr.push('z');
arr; // ['x', 'y', undefined, undefined, 'z'] — ...or when using `Array.prototype.push`
</code></pre>
<p>Now you know the &#8220;special&#8221; nature of Array objects in Javascript, which is in the relationship between &#8220;length&#8221; and numeric properties. One little detail we haven&#8217;t looked at is that array&#8217;s &#8220;length&#8221; property MUST always have a value of non-negative integer less than 2^32. Whenever this condition is violated, a <code>RangeError</code> is thrown:</p>
<pre lang="javascript"><code>
var arr = [];
arr.length = Math.pow(2, 32); // RangeError

arr.length; // 0 (length is still 0, as it initially was)

arr.length = Math.pow(2, 32) - 1; // set length to maximum allowed value

arr.length++; // RangeError (when setting length explicitly)
arr.push(1); // RangeError (or when setting length implicitly)
</code></pre>
<h3 id="function_objects_and_construct">Function objects and [[Construct]]</h3>
<p>It should start to make sense why there are discrepancies in behavior of objects created via <code>SubArray</code> and <code>Array</code> functions. Even though <code>SubArray</code> creates an object that inherits from <code>Array.prototype</code>, that <strong>object completely lacks array&#8217;s special behavior</strong>. The SubArray instance is nothing more than a plain <code>Object</code> object (as if it was created via an object literal — <code>{ }</code>).</p>
<p>But why does <code>SubArray</code> create an <code>Object</code> object and not an <code>Array</code> object? The core of this issue is in the way functions work in ECMAScript.</p>
<p>When <code>new</code> operator is applied to an object — as in <code>new SubArray</code> — that object&#8217;s internal [[Construct]] method is called. In our case, it is [[Construct]] of <code>SubArray</code> function. <code>SubArray</code> — being a native function — has [[Construct]] that&#8217;s specified to <strong>create a plain <code>Object</code> object</strong>, and invoke corresponding function providing newly created object as <code>this</code> value. Any native function, including <code>SubArray</code>, should create an <code>Object</code> object and return it as a result.</p>
<p>Now it&#8217;s worth mentioning that it&#8217;s possible to sort of supersede return value of [[Construct]] by explicitly returning non-primitive value from constructor function:</p>
<pre lang="javascript"><code>
function SubArray() {
  this.push.apply(this, arguments);
  return []; // return array object explicitly
}
</code></pre>
<p>— but in that case, returned object does NOT inherit from constructor&#8217;s &#8220;prototype&#8221; (<code>SubArray.prototype</code> in this case); neither is constructor function invoked with that object as <code>this</code> value:</p>
<pre lang="javascript"><code>
var sub = new SubArray(1, 2, 3);

// Object doesn't have 1, 2, 3, as constructor was never called with `this` value referencing returned object
sub; // []

// SubArray is not in the prototype chain of returned object
sub instanceof SubArray; // false
</code></pre>
<p>As you can see, creating an object that inherits from <code>Array.prototype</code> is only part of the story. The biggest issue is to <strong>preserve the special relation of length and numeric properties</strong>. This is why using regular <code>clone</code> approach is not quite up to the task.</p>
<h3 id="the_importance_of_array_special_behavior">The importance of array special behavior</h3>
<p>A reasonable question at this point is — &#8220;Why does array special behavior matter&#8221;? Why would we want to preserve relationship between length and numeric properties when subclassing an array? It turns out that consequences of proper length are not only visible when working with length directly, but also indirectly, when performing other tasks via <code>Array.prototype.*</code> methods.</p>
<p>Take for example <code>Array.prototype.push</code> — a method to append items to the end of array. To determine from which position to start inserting elements into, <code>push</code> <strong>retrieves a value of array&#8217;s &#8220;length&#8221;</strong>. If length is not preserved properly, elements are inserted at the wrong location:</p>
<pre lang="javascript"><code>
var arr = ['x', 'y'];
arr.length = 5;
arr.push('z'); // 'z' is inserted at 5th index, since that is what the value of "length" is
arr; // ['x', 'y', undefined, undefined, undefined, 'z']
</code></pre>
<p>Take another method — <code>Array.prototype.join</code>. Used to return a representation of an array by concatenating all elements with a separator, <code>Array.prototype.join</code> <strong>also uses length property</strong> to determine when to stop concatenating values:</p>
<pre lang="javascript"><code>
var arr = ['x', 'y'];
arr.join(); // "x,y"
arr.length = 5;
arr.join(); // "x,y,,,"
</code></pre>
<p>Same goes for <code>Array.prototype.concat</code> — method used to produce a new array by concatenating values passed to <code>concat</code>:</p>
<pre lang="javascript"><code>
var arr = ['x'];
arr.length = 3;
arr.concat('y'); // ['x', undefined, undefined, 'y']
</code></pre>
<p>Finally, the special behavior is often cleverly exploited in other situations, such as to &#8220;clear&#8221; an array (i.e. delete all of its numeric properties):</p>
<pre lang="javascript"><code>
var arr = [1, 2, 3];
arr.length = 0;
arr; // [] — setting length to 0 effectively removes all numeric properties (elements) of an array
</code></pre>
<h3 id="existing_solutions">Existing solutions</h3>
<p>Now that we're familiar with the theory, let's see what the situation is with subclassing arrays in practice. There have been few attempts in the past, with various levels of &#8220;success&#8221;. Here are a couple of most popular ones:</p>
<h4 id="andrea_giammarchi_solution">Andrea Giammarchi solution</h4>
<p>One of the recent implementations is <a href="http://webreflection.blogspot.com/2008/05/habemus-array-unlocked-length-in-ie8.html">Stack, by Andrea Giammarchi</a>, which looks like this:</p>
<pre lang="javascript"><code>
var Stack = (function(){ // (C) Andrea Giammarchi - Mit Style License

  function Stack(length) {
    if (arguments.length === 1 &#038;&#038; typeof length === "number") {
      this.length = -1 < length &#038;&#038; length === length << 1 >> 1 ? length : this.push(length);
    }
    else if (arguments.length) {
      this.push.apply(this, arguments);
    }
  };

  function Array() { };
  Array.prototype = [];

  Stack.prototype = new Array;
  Stack.prototype.length = 0;
  Stack.prototype.toString = function () {
    return this.slice(0).toString();
  };  

  Stack.prototype.constructor = Stack;
  return Stack;
})();
</code></pre>
<p>It's an interesting solution, which mainly works around IE&lt;8 bug with <code>Array.prototype.push</code> and <code>length</code> property. However, as should be obvious by now, it doesn't really solve the problem of maintaining relation between <code>length</code> and numeric properties:</p>
<pre lang="javascript"><code>
var stack = new Stack('x', 'y');
stack.length;           // 2

// so far so good

stack.push('z');
stack.length;           // 3

// still good

stack[3] = 'foo';
stack.length;           // 3

// not good anymore (length should have been changed to 4)

stack.length = 2;
stack[2];               // 'z'

// still not good (element at 2nd index should have been deleted)
</code></pre>
<h4 id="dean_edwards_solution">Dean Edwards solution</h4>
<p>Another <a href="http://dean.edwards.name/weblog/2006/11/hooray/">popular solution is by Dean Edwards</a>. This one takes a completely different approach — instead of creating an object that inherits from <code>Array.prototype</code>, an actual <code>Array</code> constructor is "borrowed" from the context of another iframe. </p>
<pre lang="javascript"><code>
// create an &lt;iframe>
var iframe = document.createElement("iframe");
iframe.style.display = "none";
document.body.appendChild(iframe);

// write a script into the &lt;iframe> and steal its Array object
frames[frames.length - 1].document.write(
  "&lt;script>parent.Array2 = Array;<\/script>";
);
</code></pre>
<p>The reason this &#8220;works&#8221; is due to browsers creating separate execution environments for each frame in a document. Each such environment has a separate set of both — built-in and host objects. Built-in objects include global <code>Array</code> constructor, among others. <code>Array</code> object of one iframe is different from <code>Array</code> object of another iframe. They also don&#8217;t have any kind of hierarchical relation:</p>
<pre lang="javascript"><code>
// assuming that SubArray was borrowed from another iframe

var sub = new SubArray(1, 2, 3);

sub instanceof SubArray; // true
sub instanceof Array; // false
sub instanceof Object; // false
</code></pre>
<p>Notice how <code>sub</code> is reported as NOT an instance of <code>Array</code>, and NOT an instance of <code>Object</code>. This is because neither <code>Array</code>, nor <code>Object</code> are anywhere in the prototype chain of <code>sub</code> object. Instead, prototype chain consists of <code>SubArray.prototype</code>, followed by <code>&lt;Object from another iframe&gt;.prototype</code>:</p>
<pre lang="javascript"><code>
new SubArray()
    |
    | [[Prototype]]
    |
    v
<another iframe>.Array.prototype
    |
    | [[Prototype]]
    |
    v
<another iframe>.Object.prototype
    |
    | [[Prototype]]
    |
    v
   null
</code></pre>
<p>This brings us to one &#8220;consideration&#8221; with this approach — difficulties determining the nature of an object derived from such iframe. It&#8217;s no longer possible to determine that an object is an array using <code>instanceof</code> or <code>constructor</code> checks <sup>[1]</sup>:</p>
<pre lang="javascript"><code>
  // is this object an array?

  sub instanceof Array; // false
  sub.constructor === Array; // false
</code></pre>
<p>It is, however, still possible to use [[Class]] check (we&#8217;ll talk about [[Class]] later on):</p>
<pre lang="javascript"><code>
  Object.prototype.toString.call(sub) === '[object Array]'; // true
</code></pre>
<p>Another, more inherent, downside of this approach is that it <strong>doesn&#8217;t work in non-browser environments</strong> (or, more precisely, in any environment without support for iframes). This problem is likely to become even bigger, given that server-side Javascript implementations are rising quite fast.</p>
<p>Finally, it was reported that <code>Array</code> borrowing can cause mixed content warning in IE6, among few other minor issues.</p>
<p>Other than that, iframe-based array &#8220;subclassing&#8221; is free of downsides of solutions like Stack, since we&#8217;re dealing with real array objects, and so proper length/indices relation.</p>
<h3 id="ecmascript_5_accessors_to_the_rescue">ECMAScript 5 accessors to the rescue</h3>
<p>But let&#8217;s talk about ECMAScript 5, which as I mentioned in the beginning, brings something that helps with subclassing arrays. This &#8220;something&#8221; is actually nothing but property accessors. These useful language constructs have been present in some popular implementations (SpiderMonkey, JavaScriptCore, and others) as a non-standard extension for quite a while now. They are now standardized by the new edition of the language.</p>
<p>Using accessors, it&#8217;s rather trivial to <strong>create an <code>Object</code> object with special length/indices relation</strong> — relation that&#8217;s identical to that of <code>Array</code> objects! And since we already know how to create an object with <code>Array.prototype</code> in its prototype chain, combining these two aspects would allow for a complete emulation of arrays.</p>
<p>There&#8217;s one little detail about implementation. Since ECMAScript (including last, 5th version) doesn&#8217;t provide any catch-all (aka <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Object/noSuchMethod">__noSuchMethod__</a>) mechanism, it&#8217;s not possible to change value of <code>length</code> property of an object when numeric property is modified; in other words, we can&#8217;t intercept the moment when &#8216;0&#8217;, &#8216;1&#8217;, &#8216;2&#8217;, &#8216;15&#8217;, etc. properties are being set. However, accessors allow us to <strong>intercept any read access</strong> of <code>length</code> property and return proper value, depending on which numeric properties object has at that moment. This is all we really need.</p>
<p>Here&#8217;s an implementation of it, at about 45 lines of code:</p>
<pre lang="javascript"><code>
var makeSubArray = (function(){

  var MAX_SIGNED_INT_VALUE = Math.pow(2, 32) - 1,
      hasOwnProperty = Object.prototype.hasOwnProperty;

  function ToUint32(value) {
    return value >>> 0;
  }

  function getMaxIndexProperty(object) {
    var maxIndex = -1, isValidProperty;

    for (var prop in object) {

      isValidProperty = (
        String(ToUint32(prop)) === prop &#038;&#038;
        ToUint32(prop) !== MAX_SIGNED_INT_VALUE &#038;&#038;
        hasOwnProperty.call(object, prop));

      if (isValidProperty &#038;&#038; prop > maxIndex) {
        maxIndex = prop;
      }
    }
    return maxIndex;
  }

  return function(methods) {
    var length = 0;
    methods = methods || { };

    methods.length = {
      get: function() {
        var maxIndexProperty = +getMaxIndexProperty(this);
        return Math.max(length, maxIndexProperty + 1);
      },
      set: function(value) {
        var constrainedValue = ToUint32(value);
        if (constrainedValue !== +value) {
          throw new RangeError();
        }
        for (var i = constrainedValue, len = this.length; i < len; i++) {
          delete this[i];
        }
        length = constrainedValue;
      }
    };
    methods.toString = {
      value: Array.prototype.join
    };
    return Object.create(Array.prototype, methods);
  };
})();
</code></pre>
<p>We can now create &#8220;sub arrays&#8221; via <code>makeSubArray</code> function. It accepts one argument — an object with methods to add to [[Prototype]] of returned &#8220;sub array&#8221;.</p>
<pre lang="javascript"><code>
var subMethods = {
  last: {
    value: function() {
      return this[this.length - 1];
    }
  }
};
var sub = makeSubArray(subMethods);
var sub2 = makeSubArray(subMethods);
// etc.
</code></pre>
<p>We can also hide this factory method behind a constructor, to make it similar to <code>Array</code>&#8217;s one:</p>
<pre lang="javascript"><code>
var SubArray = (function() {
  var methods = {
    last: {
      value: function() {
        return this[this.length - 1];
      }
    }
  };
  return function() {
    var arr = makeSubArray(methods);
    if (arguments.length === 1) {
      arr.length = arguments[0];
    }
    else {
      arr.push.apply(arr, arguments);
    }
    return arr;
  };
})();
</code></pre>
<p>And then use it as you would use regular <code>Array</code> constructor:</p>
<pre lang="javascript"><code>
var sub = new SubArray(1, 2, 3);

sub.length; // 3
sub; // [1, 2, 3]

sub.length = 1;
sub; // [1]

sub[10] = 'x';
sub.push(1);
</code></pre>
<p>You can find this version of <code>SubArray</code> together with unit tests in <a href="https://github.com/kangax/array_subclassing">Gtihub repository</a>. For brevity, I made this implementation mainly take care of length/indices relation; certain methods (e.g. <code>concat</code>) do not behave identical to <code>Array</code> and need to be implemented accordingly.</p>
<h3 id="class_limitations">[[Class]] limitations</h3>
<p>The implementation we have just seen — the one utilizing property accessors — is great. It doesn&#8217;t require any host objects (such as iframes); it preserves relation between length and numeric properties; it even disallows out-of-range values for length or indices. All it requires is support for ES5 (or even just <code>Object.create</code> method).</p>
<p>But the dramatic title of this post is not there just for fun. There&#8217;s one little detail we&#8217;re missing in this otherwise complete implementation. And that detail is <strong>proper [[Class]] value</strong> — something that ECMAScript still doesn&#8217;t give full control over.</p>
<p>I wrote about [[Class]] before, when <a href="http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/">explaining how to detect  arrays</a>. In a nutshell, [[Class]] is an internal property of objects in ECMAScript. Its value is never exposed directly, but can still be inspected using certain methods (e.g. <code>Object.prototype.toString</code>). The usefulness of [[Class]] is that it allows to detect type of objects without relying on <code>instanceof</code> operator or checking object&#8217;s <code>constructor</code> — both of which fall short to detect objects from other contexts (e.g. iframes), as we&#8217;ve seen earlier.</p>
<p>Now, since objects created by <code>makeSubArray</code> are nothing but plain <code>Object</code> objects (only with special <code>length</code> getters/setters), <strong>their [[Class]] is also that of &#8220;Object&#8221; not an &#8220;Array&#8221;</strong>! We&#8217;ve taken care of length/indices relation, we&#8217;ve set up <code>Array.prototype</code> inheritance, but there&#8217;s no way to change object&#8217;s [[Class]] value. And so this solution can not claim to be complete.</p>
<h3 id="does_class_matter">Does [[Class]] matter?</h3>
<p>You might be wondering — what are the actual implications of these pseudo-array objects having [[Class]] of &#8220;Object&#8221; not an &#8220;Array&#8221;. Do we even care? Well, for once, there&#8217;s an issue with object detection. Ironically, the solution I proposed to detect arrays relies on [[Class]], and so would fall short with objects like these.</p>
<pre lang="javascript"><code>
// assuming that `sub` is a pseudo-array
Object.prototype.toString.call(sub) === '[object Array]'; // false
</code></pre>
<p>Another, probably more important, implication is that some of the <strong>methods in ECMAScript actually rely on [[Class]] value</strong>. For example, a well-known <code>Function.prototype.apply</code> accepts an array as its second argument (as well as an <code>arguments</code> object). Section 15.3.4.3 of ES3 says — <cite>&#8220;if argArray is neither an array nor an arguments object (see 10.1.8), a TypeError exception is thrown&#8221;</cite>. What this means is that if we pass pseudo-array object as a second argument to <code>apply</code> it will throw TypeError. <code>apply</code> doesn&#8217;t know or care if an object inherits from <code>Array.prototype</code>; neither does it care about object implementing special length/indices behavior. All it cares is that <strong>object is of proper type</strong> — type that we, unfortunately, can not emulate.</p>
<pre lang="javascript"><code>
// assuming that `sub` is a pseudo-array
someFunction.apply(this, sub); // TypeError
</code></pre>
<p>There&#8217;s some vagueness in specification on this matter. For example, in <code>Date.prototype.setTime</code> spec says <cite>&#8220;If the this value is <strong>not a Date object</strong>, throw a TypeError exception.&#8221;</cite>, but in <code>Date.prototype.getTime</code>, it uses [[Class]] rather than just &#8220;not a Date object&#8221; — <cite>&#8220;If the this value is <strong>not an object whose [[Class]]</strong> property is &#8220;Date&#8221;, throw a TypeError exception&#8221;</cite>.</p>
<p>It&#8217;s probably safe to assume that these 2 phrases — &#8220;Date object&#8221; and &#8220;object with [[Class]] of &#8216;Date&#8217;&#8221; — have identical meaning. Ditto for &#8220;Array object&#8221; and &#8220;object with [[Class]] of &#8216;Array&#8217;&#8221;, as well as others.</p>
<p><code>Function.prototype.apply</code> is not the only method sensitive to [[Class]] of an object. <code>Array.prototype.concat</code>, for example, follows different algorithm based on whether an object is an array or not (in other words — whether it has [[Class]] of &#8220;Array&#8221; or not).</p>
<pre lang="javascript"><code>
// array ([[Class]] == "Array")
var arr = ['x', 'y'];

// object with numeric properties ([[Class]] == "Object")
var obj = { '0': 'x', '1': 'y' };

[1,2,3].concat(arr); // [1, 2, 3, 'x', 'y']
[1,2,3].concat(obj); // [1, 2, 3, { '0': 'x', '1': 'y' }]
</code></pre>
<p>As you can see, array values are &#8220;flattened&#8221;, whereas non-array ones are left as is. It is certainly possible to give these pseudo-arrays custom implementation of <code>concat</code> (and &#8220;fix&#8221; any other of <code>Array.prototype.*</code> methods), but <strong>the problem with <code>Function.prototype.apply</code> can not be solved</strong>.</p>
<p>It&#8217;s worth mentioning that another downside of accessor-based pseudo-array approach is performance. I haven&#8217;t done any tests, but it&#8217;s pretty clear that an implementation which has to <strong>enumerate over all numeric properties</strong> on every access of <code>length</code> property is not going to perform well. This is why <strong>I can't recommend this solution</strong> for anything other than educational purposes.</p>
<h3 id="wrappers_direct_property_injection">Wrappers. Direct property injection.</h3>
<p>Realizing a somewhat futile nature of subclassing arrays in Javascript often <strong>makes alternative solutions look very attractive</strong>. One of such solutions is using wrappers. Wrapper approach avoids setting up inheritance or emulating length/indices relation. Instead, a factory-like function can create a plain Array object, and then <strong>augment it directly</strong> with any custom methods. Since returned object is an Array one, it maintains proper length/indices relation, as well as [[Class]] of &#8220;Array&#8221;. It also inherits from <code>Array.prototype</code>, naturally.</p>
<pre lang="javascript"><code>
function makeSubArray() {
  var arr = [ ];
  arr.push.apply(arr, arguments);
  arr.last = function() {
    return this[this.length - 1];
  };
  return arr;
}

var sub = makeSubArray(1, 2, 3);
sub instanceof Array; // true

sub.length; // 3
sub.last(); // 3
</code></pre>
<p>While direct extension of array object is a beautiful, simplistic solution, it&#8217;s not without downsides. The main disadvantage is that on each invocation of constructor, <strong>an array needs to be extended with N number of methods</strong>. The time it takes to create an array is no longer a constant (if methods were on <code>SubArray.prototype</code>), but is directly proportional to the number of methods that need to be added. </p>
<h3 id="wrappers_prototype_chain_injection">Wrappers. Prototype chain injection.</h3>
<p>To overcome the problem of &#8220;N methods&#8221;, another variation of wrappers can be used — the one in which object&#8217;s prototype chain is augmented, rather than object itself. Let&#8217;s see how this could be done:</p>
<pre lang="javascript"><code>
function SubArray() { }
SubArray.prototype = new Array;
SubArray.prototype.last = function() {
  return this[this.length - 1];
};

function makeSubArray() {
  var arr = [ ];
  arr.push.apply(arr, arguments);
  arr.__proto__ = SubArray.prototype;
  return arr;
}
</code></pre>
<p>The idea is simple. When <code>makeSubArray</code> function is executed, two things happen: 1) an array object is created and is populated with any passed arguments; 2) object&#8217;s prototype chain is augmented in such way so that next object is <code>SubArray.prototype</code>, not original <code>Array.prototype</code>. The augmentation of prototype chain is done via <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Object/Proto">non-standard __proto__ property</a>. </p>
<p>But what happens in <code>makeSubArray</code> function is of course only half of the story. To make sure that object has <code>Array.prototype</code> in its prototype chain, we need to make <code>SubArray.prototype</code> inherit from it. This is exactly what&#8217;s being done on a second line of this snippet (<code>SubArray.prototype = new Array</code>). Prototype chain of an object returned from <code>makeSubArray</code> now looks like this:</p>
<pre lang="javascript"><code>
new SubArray()
    |
    | [[Prototype]]
    |
    v
SubArray.prototype
    |
    | [[Prototype]]
    |
    v
Array.prototype
    |
    | [[Prototype]]
    |
    v
Object.prototype
    |
    | [[Prototype]]
    |
    v
   null
</code></pre>
<p>And because returned object is actually an <code>Array</code>, not an <code>Object</code> one, we also get length/indices relation as well as proper [[Class]] value. In fact, we can go even further and move initialization logic into <code>SubArray</code> constructor itself:</p>
<pre lang="javascript"><code>
function SubArray() {
  var arr = [ ];
  arr.push.apply(arr, arguments);
  arr.__proto__ = SubArray.prototype;
  return arr;
}
SubArray.prototype = new Array;
SubArray.prototype.last = function() {
  return this[this.length - 1];
};

var sub = new SubArray(1, 2, 3);

sub instanceof SubArray; // true
sub instanceof Array; // true
</code></pre>
<p>Even though augmenting prototype chain is a more performant solution, there&#8217;s a clear downside — <strong>it relies on non-standard __proto__ property</strong>. ECMAScript, unfortunately, does not allow to set [[Prototype]] of an object — internal property referencing immediate ancestor in its prototype chain. Not even in 5th edition. Even though __proto__ is supported by a rather large number of implementations, it is far from being truly compatible.</p>
<h3 id="summary">Summary</h3>
<p>So here it is; all the fun intricacies of subclassing arrays in Javascript. </p>
<p>We&#8217;ve seen that contrary to what might seem, <strong>actual inheritance is by far not the only aspect</strong> of subclassing arrays in Javascript; that arrays are different from regular objects by having <strong>special length/indices relation</strong>; how this length/indices relation is important and has nothing to do with prototype chain of an object; how arrays have special [[Class]] value of &#8220;Array&#8221; which is also rather important, and isn&#8217;t inherited either; how it&#8217;s <strong>not possible to change [[Class]] value</strong> of an object — not even in ECMAScript 5. We looked at different ways to &#8220;subclass&#8221; an array, starting from borrowing <code>Array</code> constructors from other contexts, and ending with augmentation of prototype chain. We examined benefits and downsides of each one of those solutions.</p>
<p>What we haven&#8217;t touched upon is the performance metrics of each of the implementations — perhaps a good topic for another discussion.</p>
<p>On this note, I leave you with a table summarizing pros/cons of the above mentioned techniques.</p>
<table class="array-subclass-implementations">
<thead>
<tr>
<td></td>
<th>Proper [[Class]]</th>
<th>length/indices</th>
<th>Uses native objects only</th>
<th>Requires ES3 only</th>
</tr>
</thead>
<tbody>
<tr>
<th>Stack (Andrea Giammarchi)</th>
<td class="no">No</td>
<td class="no">No</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<th>IFrame borrowing (Dean Edwards)</th>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="no">No</td>
<td class="yes">Yes</td>
</tr>
<tr>
<th>Accessors</th>
<td class="no">No</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="no">No</td>
</tr>
<tr>
<th>Direct extension</th>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<th>Prototype extension</th>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="no">No</td>
</tr>
</tbody>
</table>
<p><span style="font-size:0.85em"><sup>[1]</sup> Whether this endeavor is something worth pursuing is a topic for another discussion</span></p>
<p>P.S. Big thanks to <a href="http://twitter.com/jdalton">John David Dalton</a> for reviewing an article and giving useful suggestions.</p>
</div>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerfectionKills?a=-VkH0LKhxI8:nRLkUd1i6UI:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerfectionKills?i=-VkH0LKhxI8:nRLkUd1i6UI:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerfectionKills/~4/-VkH0LKhxI8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		<feedburner:origLink>http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/</feedburner:origLink></item>
		<item>
		<title>JScript and DOM changes in IE9 preview 3</title>
		<link>http://feedproxy.google.com/~r/PerfectionKills/~3/JdYE5em4J6M/</link>
		<comments>http://perfectionkills.com/jscript-and-dom-changes-in-ie9-preview-3/#comments</comments>
		<pubDate>Thu, 24 Jun 2010 15:19:04 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[ECMA-262]]></category>
		<category><![CDATA[isArray]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[strict-mode]]></category>
		<category><![CDATA[[[Class]]]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=269</guid>
		<description><![CDATA[3rd preview of IE9 was released yesterday, with some amazing additions, like canvas element and an extensive ES5 support. I&#8217;ve been digging through it a little, to see what has changed and what hasn&#8217;t — mainly looking at JScript and DOM. I posted some of the findings on twitter, but want to also list them [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blogs.msdn.com/b/ie/archive/2010/06/23/html5-native-third-ie9-platform-preview-available-for-developers.aspx">3rd preview of IE9 was released yesterday</a>, with some amazing additions, like canvas element and an extensive <abbr title="ECMAScript 5">ES5</abbr> support. I&#8217;ve been digging through it a little, to see what has changed and what hasn&#8217;t — mainly looking at JScript and DOM. I posted some of <a href="http://search.twitter.com/search?q=kangax+%23ie9pre3">the findings on twitter</a>, but want to also list them here, as it&#8217;s not very convenient to share code snippets in 140 characters. Referencing it all in one place will hopefully make it easier for IE team to find and fix these deficiencies.</p>
<h2 id="ecmascript_5_and_jscript">ECMAScript 5 and JScript</h2>
<p>The big news is that IE9pre3 has (almost) full support for ES5. By &#8220;full support&#8221;, I mean that it implements majority of new API, such as <code>Object.create</code>, <code>Object.defineProperty</code>, <code>String.prototype.trim</code>, <code>Array.isArray</code>, <code>Date.now</code>, and many other additions. As of now, IE9 implements the largest number of new methods; even more than latest Chrome, Safari and Firefox. Unbelievable, isn&#8217;t it? :)</p>
<p><img src="http://perfectionkills.com/images/ie9pre3.png" alt="screenshot of es5 compatibility table"></p>
<p>You can see the results in <a href="http://kangax.github.com/es5-compat-table/">this compatibility table</a> (note that it lists results of mere &#8220;existence&#8221; testing, not any kind of conformance).</p>
<p>What&#8217;s missing is strict mode, which actually isn&#8217;t implemented in any of the browsers yet.</p>
<p>Some of the things I noticed:</p>
<p>ES5 <code>Object.getPrototypeOf</code> on host objects seems to lie, always returning <code>null</code> instead of proper value of [[Prototype]]:</p>
<pre lang="javascript"><code>
  Object.getPrototypeOf(document.body); // null
  Object.getPrototypeOf(document); // null
  Object.getPrototypeOf(alert); // null
  Object.getPrototypeOf(document.childNodes); // null
</code></pre>
<p>This doesn&#8217;t happen in other browsers that implement <code>Object.create</code> at the moment, such as latest Chrome, WebKit or Firefox. In Chrome, for example:</p>
<pre lang="javascript"><code>
  Object.getPrototypeOf(document.body) === HTMLBodyElement.prototype;
  Object.getPrototypeOf(document) === HTMLDocument.prototype;
  Object.getPrototypeOf(alert) === Function.prototype;
  Object.getPrototypeOf(document.childNodes) === NodeList.prototype
</code></pre>
<p>&#8230; and so on.</p>
<p>Interestingly, bound functions in IE9pre3 are represented as &#8220;function(){ [native code] }&#8221;, similar to host objects:</p>
<pre lang="javascript"><code>
  var bound = (function f(x, y){ return this; }).bind({ x: 1 });
  bound + ''; // "function(){ [native code] }"

  // compare to

  alert + ''; // "function alert(){ [native code] }"
</code></pre>
<p>Note how function representation does not include identifier (<code>f</code>), parameters (<code>x</code> and <code>y</code>), nor representation of function body (<code>return this;</code>). This of course proves once again that <a href="http://perfectionkills.com/those-tricky-functions/">relying on function decompilation is NOT a good idea</a>.</p>
<p>Whitespace character class (as in <code>/\s/</code>) still doesn&#8217;t match <a href="http://perfectionkills.com/whitespace-deviations/">majority of whitespace characters</a> (as defined by specs). These include &#8220;U+00A0&#8221;, &#8220;U+2000&#8221; to &#8220;U+200A&#8221;, &#8220;U+3000&#8221;, etc. The test is <a href="http://yura.thinkweb2.com/rcornford_whitespace_test.html">available here</a>. Curiously, ES5 <code>String.prototype.trim</code> seems to &#8220;understand&#8221; those characters as whitespace very well, producing empty string — as expected — for something like <code>'\u00A0'.trim()</code>.</p>
<p>It was nice to see that ES5 <code>Array.isArray</code> is about 20 times faster than custom implementation, such as this one:</p>
<pre lang="javascript"><code>
  function isArray(o) {
    return Object.prototype.toString.call(o) === "[object Array]";
  }
</code></pre>
<p>The difference in speed is similar to other browsers that implement this method.</p>
<p>An infamous, 10+ year-old JScript NFE bug, <a href="http://yura.thinkweb2.com/named-function-expressions/#jscript-bugs">which I described at length before</a>, is finally fixed:</p>
<pre lang="javascript"><code>
  var f = function g() { return f === g; };
  typeof g; // "undefined"

  f(); // true
</code></pre>
<p><code>arguments</code>&#8217; [[Class]] is now an &#8220;Arguments&#8221;, just like ES5 specifies it:</p>
<pre lang="javascript"><code>
  var args = (function(){ return arguments; })();
  Object.prototype.toString.call(args); // "[object Arguments]"
</code></pre>
<h2 id="dom">DOM</h2>
<p>Unfortunately, the entire host objects infrastructure still looks very similar to the one from IE8. Host objects don&#8217;t inherit from <code>Object.prototype</code>, don&#8217;t report proper <code>typeof</code>, and don&#8217;t even have basic properties like &#8220;length&#8221; or &#8220;prototype&#8221;, which all function objects must have:</p>
<pre lang="javascript"><code>
  alert instanceof Object; // false
  typeof alert; // "object"
  alert.length; // undefined
</code></pre>
<p>Because they don&#8217;t inherit from <code>Object.prototype</code>, we don&#8217;t have any of <code>Object.prototype</code> methods, naturally:</p>
<pre lang="javascript"><code>
  alert.toString; // undefined
  alert.constructor; // undefined
  alert.hasOwnProperty; undefined
</code></pre>
<p><code>Object.prototype</code> is not the only object host methods fail to inherit from. In majority of modern browsers, host objects also inherit from <code>Function.prototype</code> and so have <code>Function.prototype</code> methods like <code>call</code> and <code>apply</code>. This doesn&#8217;t happen in IE9pre3.</p>
<pre lang="javascript"><code>
  alert instanceof Function; // false
  document.createElement instanceof Function; // false

  alert.call; // undefined
</code></pre>
<p>Curiously, <code>call</code> and <code>apply</code> are present on some host objects, but they are still not inherited from <code>Function.prototype</code>:</p>
<pre lang="javascript"><code>
  typeof document.createElement.call; // "function"
  document.createElement.call === Function.prototype.call; // false
</code></pre>
<p>Host objects&#8217; [[Class]] is far from ideal as well. IE9pre3 actually violates ES5, which says that objects implementing [[Call]] (or in other words — are callable) should have [[Class]] of &#8220;Function&#8221; — even if they are host objects. In IE9pre3, <code>alert</code> is a callable host object, yet it reports its [[Class]] as &#8220;Object&#8221; not &#8220;Function&#8221;. Not good.</p>
<pre lang="javascript"><code>
  Object.prototype.toString.call(alert); // "[object Object]"
  Object.prototype.toString.call(document.createElement); // "[object Object]"
</code></pre>
<p>IE9pre3 still messes up DOM objects&#8217; attributes and properties, although not as badly as earlier versions:</p>
<pre lang="javascript"><code>
  var el = document.createElement('p');
  el.setAttribute('x', 'y');
  el.x; // 'y'

  el.foobarbaz = 'moo';
  el.hasAttribute('foobarbaz'); // true
  el.getAttribute('foobarbaz'); // 'moo'
</code></pre>
<p>Some old, humorous bugs can still be seen in IE9pre3, such as methods returning &#8220;string&#8221; when applied <code>typeof</code> on:</p>
<pre lang="javascript"><code>
  typeof Option.create; // "string"
  typeof Image.create; // "string"
  typeof document.childNodes.item; // "string"
</code></pre>
<p>Undeclared assignments still throw error when same-id&#8217;ed elements are present in DOM, however not with same-name&#8217;ed elements (as it was in previous versions):</p>
<pre lang="javascript"><code>
<div id="foo"></div>

  <a name="bar"></a>
  ...
  <script>
    foo = function(){ /* ... */ }; // Error
    bar = function(){ /* ... */ }; // no Error
  </script>
</code></pre>
<p>Similarly to IE8, only <code>Element</code> and specific element type interfaces (<code>HTMLDivElement</code>, <code>HTMLScriptElement</code>, <code>HTMLSpanElement</code>, etc.) are exposed as same-named global properties. <code>Node</code> and <code>HTMLElement</code> are still missing, and element&#8217;s prototype chain most likely still looks like this:</p>
<pre lang="javascript"><code>
  document.createElement('div');
    |
    | [[Prototype]]
    v
  HTMLDivElement.prototype
    |
    | [[Prototype]]
    v
  Element.prototype
    |
    | [[Prototype]]
    v
  null
</code></pre>
<p>&#8230;rather than what can be seen in almost all other modern browsers:</p>
<pre lang="javascript"><code>
  document.createElement('div');
    |
    | [[Prototype]]
    v
  HTMLDivElement.prototype
    |
    | [[Prototype]]
    v
  HTMLElement.prototype
    |
    | [[Prototype]]
    v
  Element.prototype
    |
    | [[Prototype]]
    v
  Node.prototype
    |
    | [[Prototype]]
    v
  Object.prototype
    |
    | [[Prototype]]
    v
  null
</code></pre>
<p><code>getComputedStyle</code> from DOM Level 2 is still missing, however its value is mysteriously a <code>null</code>, not <code>undefined</code>. The property actually exists on an object, but has a value of <code>null</code>. Hopefully, this is just a placeholder and proper method will be added before final release.</p>
<pre lang="javascript"><code>
  document.defaultView.getComputedStyle; // null
  'getComputedStyle' in document.defaultView; // true
</code></pre>
<p><code>Array.prototype.slice</code> can now convert certain host objects (e.g. <code>NodeList</code>&#8217;s) to arrays — something that majority of modern browsers have been able to do for quite a while:</p>
<pre lang="javascript"><code>
  Array.prototype.slice.call(document.childNodes) instanceof Array; // true
</code></pre>
<p>That&#8217;s it for now.</p>
<p>Unfortunately, I don&#8217;t have much time to look into these things extensively, at the moment. There might be more updates on <a href="http://twitter.com/kangax">twitter</a>.</p>
<p>As always, any corrections, suggestions, and additions are much appreciated.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerfectionKills?a=JdYE5em4J6M:x9TD6BIypgo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerfectionKills?i=JdYE5em4J6M:x9TD6BIypgo:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerfectionKills/~4/JdYE5em4J6M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/jscript-and-dom-changes-in-ie9-preview-3/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		<feedburner:origLink>http://perfectionkills.com/jscript-and-dom-changes-in-ie9-preview-3/</feedburner:origLink></item>
		<item>
		<title>Tag is not an element. Or is it?</title>
		<link>http://feedproxy.google.com/~r/PerfectionKills/~3/XFQaTaj7XAY/</link>
		<comments>http://perfectionkills.com/tag-is-not-an-element-or-is-it/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 16:08:55 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[don'ts]]></category>
		<category><![CDATA[html]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=230</guid>
		<description><![CDATA[It&#8217;s interesting how widely some misconceptions spread around. The one I noticed recently is the &#8220;issue&#8221; of elements vs. tags. The problem is that people say tags when they mean elements, and do it so often that it&#8217;s not clear if the distinction is still relevant. Or if anyone even cares anymore. Elements vs. tags [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s interesting how widely some misconceptions spread around. The one I noticed recently is the &#8220;issue&#8221; of elements vs. tags. The problem is that people say tags when they mean elements, and do it so often that it&#8217;s not clear if the distinction is still relevant. </p>
<p>Or if anyone even cares anymore.</p>
<h3 id="elements_vs_tags">Elements vs. tags</h3>
<p>If you look at section 3 of HTML 4.01 — <a href="http://www.w3.org/TR/REC-html40/intro/sgmltut.html">&#8220;on SGML and HTML&#8221;</a>, there&#8217;s an explicit note about elements not being tags. In HTML 4.01, <br /><code>&lt;p&gt;foo bar&lt;/p&gt;</code> is an element, not a tag. An element consists of a <strong>start tag</strong>,  <strong>content</strong>, and an <strong>end tag</strong>. In case of <code>&lt;p&gt;foo bar&lt;/p&gt;</code>, <code>&lt;p&gt;</code> is a start tag, <code>foo bar</code> is content, and <code>&lt;/p&gt;</code> is an end tag. </p>
<p>In other words, <strong>elements consist of tags</strong>.</p>
<h3 id="optional_tags">Optional tags</h3>
<p>The distinction between tags and elements becomes slightly less clear once we start dealing with elements that have optional tags, as defined by HTML 4.01. For example, <code>&lt;p&gt;</code> or <code>&lt;td&gt;</code> elements don&#8217;t have to have end tags. They could very well exist without them. When parser finds <code>&lt;p&gt;foo bar</code> in markup, it <strong>still creates an element</strong>. There&#8217;s no end <code>&lt;/p&gt;</code> tag, but parser doesn&#8217;t really need it; start <code>&lt;p&gt;</code> tag already denotes what kind of element it is.</p>
<pre lang="html"><code>
  &lt;p>foo bar

  &lt;tr>
    &lt;td>baz
    &lt;td>qux
  &lt;/tr>
</code></pre>
<p>But that&#8217;s not all.</p>
<p>Some elements, besides having optional end tags, have <a href="http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.3.3">empty content model</a>, which means that they can&#8217;t have any content at all. And when an element is not allowed to have any content and has an optional tag, it&#8217;s called an empty element. Not only are end tags optional in such elements, but they <strong>must be completely omitted</strong>. These, unfortunately, are not some obscure elements, but are very much useful ones like <code>&lt;br&gt;</code>, <code>&lt;link&gt;</code>, <code>&lt;img&gt;</code>, <code>&lt;input&gt;</code>, <code>&lt;meta&gt;</code> and few others.</p>
<p>What&#8217;s interesting is that <code>&lt;br&gt;</code> is still an element, only an element that <strong>consists of start tag only</strong>. It&#8217;s just that its content and end tag must never be present. The fact that <code>&lt;br&gt;</code>, <code>&lt;img&gt;</code> or other empty elements consist of start tags only, makes things rather confusing.</p>
<p>And we&#8217;re not even talking about elements with both tags optional — <code>&lt;html&gt;</code>, <code>&lt;head&gt;</code>, <code>&lt;body&gt;</code>. Those could exist <strong>without any visible traces at all</strong>, and are only created based on the context.</p>
<pre lang="html"><code>
  &lt;html>
    &lt;!--
            There's no HEAD start tag, no HEAD end tag, and no HEAD content here.
            Yet, HEAD element is still created implicilty.
            This happens because content model of HTML element is defined as `head, body`,
            which means that both elements should be present in HTML element in that order.
            As soon as BODY start tag is found, even if HEAD tags are not present,
            HEAD element is created automatically.  -->
    &lt;body>
    ...
    &lt;/body>
  &lt;/html>
</code></pre>
<h3 id="which_confusion">Which confusion?</h3>
<p>So which practical implications does this confusion actually have?</p>
<p>For one, saying something like &#8220;insert an image after a &lt;p> tag&#8221; is ranging from &#8220;wrong&#8221; to &#8220;ambiguous&#8221;, since we can&#8217;t insert anything but a chunk of text after a &lt;p> tag, and &lt;p> tag can be either a start one (<code>&lt;p&gt;</code>) or an end one (<code>&lt;/p&gt;</code>). In this case, a better way would be to say — &#8220;insert an &lt;img&gt; tag after a start &lt;p&gt; tag&#8221;:</p>
<pre lang="html"><code>
  &lt;p>
    &lt;img ...> &lt;!-- IMG tag is inserted after a start P tag -->
    ...
  &lt;/p>
</code></pre>
<p>in which case <code>&lt;img&gt;</code> element would become a child of <code>&lt;p&gt;</code> element. Or we could say — &#8220;insert an &lt;img&gt; tag after an end &lt;p&gt; tag&#8221;:</p>
<pre lang="html"><code>
  &lt;p>
    ...
  &lt;/p>
  &lt;img ...> &lt;!-- IMG tag is inserted after an end P tag -->
</code></pre>
<p>in which case <code>&lt;img&gt;</code> element would be a sibling following <code>&lt;p&gt;</code> one.</p>
<p>Of course, most of the time, what people really mean by &#8220;insert an image after a &lt;P&gt; tag&#8221; is a second version. It&#8217;s just that <strong>&#8220;element&#8221; is accidentally replaced with a &#8220;tag&#8221;</strong>. An even better way — and the one that avoids mention of tags in the first place — is to say &#8220;insert an &lt;IMG&gt; element after a &lt;P&gt; element&#8221;. This version leaves no room for incorrect interpretation.</p>
<h3 id="global_confusion">Global confusion</h3>
<p>What&#8217;s interesting about all this is not so much the finer points of difference between tags and elements, but just how widely this misconception prevails. Google search returns <a href="http://www.google.com/search?q=%22div+tag%22">480,000 results</a> for &#8220;div tag&#8221;, but only <a href="http://www.google.com/search?q=%22div+element%22">137,000</a> for &#8220;div element&#8221;. For an empty element, such as img, the difference is even scarier — &#8220;img tag&#8221; returns <a href="http://www.google.com/#q="img+tag"">959,000 results</a>, while &#8220;img element&#8221; only <a href="http://www.google.com/#q="img+element"">48,200</a>. An element is confused for a tag everywhere, from blogs, articles, and mailing lists to books, references, and frameworks.</p>
<ul>
<li style="margin-bottom:0.5em;">Ruby on Rails uses &#8220;tag&#8221; in all of its helpers — <a href="http://api.rubyonrails.org/classes/ActionView/Helpers/TagHelper.html#M002244">tag</a>, <a href="http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html#M002234">image_tag</a>, <a href="http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html#M002231">stylesheet_link_tag</a>, etc. — where each of those methods actually insert an element into a document.
</li>
<li style="margin-bottom:0.5em;">w3schools <a href="http://www.w3schools.com/tags/tag_div.asp">uses &#8220;tag&#8221; throughout its entire reference</a> — &#8220;&lt;div> tag&#8221;, &#8220;&lt;abrr> tag&#8221;, etc. — to refer to elements.</li>
<li style="margin-bottom:0.5em;"><a href="http://hacks.mozilla.org/2009/07/video-more-than-just-a-tag/">hacks.mozilla.org uses tag</a> when talking about HTML5 video element.</li>
<li style="margin-bottom:0.5em;"><a href="http://ajaxian.com/archives/youtube-html5-video">Ajaxian mentions it</a> here and there.</li>
<li style="margin-bottom:0.5em;">Books like <a href="http://www.amazon.com/Performance-JavaScript-Faster-Application-Interfaces/dp/059680279X">&#8220;High Performance Javascript&#8221;</a> explain things in terms of tags, rather than elements.</li>
<li style="margin-bottom:0.5em;">and many, many others&#8230;</li>
</ul>
<h3 id="pedantry_or_an_important_distinction">Pedantry or an important distinction?</h3>
<p>Once you start thinking about the distinction, edges become somewhat blurry. Are all of the examples above really wrong? </p>
<p>When describing <a href="http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html#M002234">&#8220;image_tag&#8221;</a>, Ruby on Rails documentation says <cite>&#8220;Returns an html image tag &#8230;&#8221;</cite>. The returned string — &#8220;&lt;img &#8230;&gt;&#8221; — can actually very well be considered an image (start) tag. Yes, the string represents an element, but since an element is empty, it&#8217;s also a string that consists of <code>&lt;img&gt;</code> tag only, and so can probably be called an &#8220;image&#8221; tag.</p>
<p>At the same time, <a href="http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html#M002225">&#8220;javascript_include_tag&#8221;</a> already crosses the line of correctness. It still uses <cite>&#8220;Returns an html <strong>script tag</strong>&#8221;</cite>, but already returns a string that can only be considered an element — &#8220;&lt;script type=&#8221;text/javascript&#8221; src=&#8221;&#8230;&#8221;&gt;&lt;/script&gt;&#8221;, since there&#8217;s now a start tag, content (empty), and an end tag.</p>
<p>w3schools is just plain wrong <sup><a href="#w3schools-footnote">[1]</a></sup>, saying things like <cite>&#8220;The &lt;div&gt; tag defines a division or a section in an HTML document.&#8221;</cite> or <cite>&#8220;The &lt;div&gt; tag is often used to group block-elements to format them with styles.&#8221;</cite>. Tags do not define division, they represent elements, and it is elements that have certain semantic meaning; in this case — division.</p>
<p>In some of the <a href="http://www.smashingmagazine.com/2009/08/04/designing-a-html-5-layout-from-scratch/">popular articles</a>, we can find phrases like <cite>&#8220;&#8230; the nearer ancestor of our &lt;footer&gt; tag is the &lt;body&gt; tag &#8230;&#8221;</cite>, in which case it&#8217;s pretty clear that &#8220;tag&#8221; is not the right word at all; Tags can not be ancestors, but elements can.</p>
<p>However, saying that &#8220;browser supports &lt;video&gt; tag&#8221; is technically not wrong, since browsers supporting <code>&lt;video&gt;</code> element, most definitely can parse and understand <code>&lt;video&gt;</code> tags as well (it is by recognizing video tags that they are able to create video elements in DOM).</p>
<p>Speaking of DOM&#8230;</p>
<h3 id="what_about_dom">What about DOM?</h3>
<p>Before I knew the difference between tags and elements, I would always think in terms of tags when talking about HTML, and in terms of elements when talking about DOM. It just made sense that HTML, being markup language, consists of tags, while HTML DOM — or rather, the document available for scripting — is a tree-like structure consisting of elements, and other kinds of nodes. I knew that browser parses HTML markup (and so tags), and then creates a tree-like structure to represent a document, in which case <strong>tags essentially become elements</strong>. The fact that elements are not just kinds of nodes, but are also chunks of text in markup seemed very strange when I first found out about it.</p>
<p>It seems that this is exactly how most of the people think about tags vs. elements. Tags exist in HTML (text), and elements &#8211; in document (DOM). This would explain why tags prevail in discussions about HTML, or markup in general; and why elements are mostly mentioned in context of scripting, rendering, etc.</p>
<p>Nevertheless, I believe that <strong>keeping terminology straight is important</strong>. Things should be called as they really are, to avoid the ambiguity that we&#8217;ve seen in the previous example. A method named something like <code>forEachTag</code> should not iterate over each element, and vice-versa; technical discussions, articles, and documentation should really strive to use proper terms.</p>
<h3 id="what_now">What now?</h3>
<p>The attempts at demystification were <a href="http://annevankesteren.nl/2004/05/tags-vs-elements">already made</a> in <a href="http://www.456bereastreet.com/archive/200508/html_tags_vs_elements_vs_attributes/">the past</a>, yet the effect is barely visible. So I wonder — why? Is it too unintuitive to speak in terms of elements in context of HTML, or is this a lack of explanation and exposure of the subject? Does the distinction even matter? Or does it matter in technical discussions only? Does it make sense to distinguish these two entities, or should we just try to infer the exact meaning based on the context, as it seems to be done right now? Are we all simply used to the word &#8220;tag&#8221;, and don&#8217;t care about the difference most of the time?</p>
<p>What do you think?</p>
<p id="w3schools-footnote" style="font-size:0.85em"><sup>[1]</sup> &#8230;which is not surprising, considering the amount of other misconceptions on that site, such as classifying HTML comments as tags.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerfectionKills?a=XFQaTaj7XAY:gbazQZnXG2Q:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerfectionKills?i=XFQaTaj7XAY:gbazQZnXG2Q:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerfectionKills/~4/XFQaTaj7XAY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/tag-is-not-an-element-or-is-it/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		<feedburner:origLink>http://perfectionkills.com/tag-is-not-an-element-or-is-it/</feedburner:origLink></item>
	</channel>
</rss>
