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

<channel>
	<title>Perfection kills</title>
	<atom:link href="http://perfectionkills.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://perfectionkills.com</link>
	<description>Exploring Javascript by example</description>
	<lastBuildDate>Thu, 15 Jul 2010 16:07:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>How ECMAScript 5 still does not allow to subclass an array</title>
		<link>http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/</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[[[Class]]]]></category>
		<category><![CDATA[[[Construct]]]]></category>
		<category><![CDATA[[[Prototype]]]]></category>
		<category><![CDATA[iframes]]></category>
		<category><![CDATA[isArray]]></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; }
   [...]]]></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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> sub <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> SubArray<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
sub<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// [1, 2, 3]</span>
&nbsp;
sub.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 3</span>
sub<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 2</span>
&nbsp;
sub.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
sub<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// [1, 2, 3, 4]</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// etc.</span>
&nbsp;
sub intanceof SubArray<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
sub intanceof Array<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Array.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">last</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#91;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">length</span><span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// ...</span>
<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">last</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 3</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> clone<span style="color: #009900;">&#40;</span>obj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">function</span> F<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
  F.<span style="color: #660066;">prototype</span> <span style="color: #339933;">=</span> obj<span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">new</span> F<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>and then set-up inheritance like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> Child<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
Child.<span style="color: #660066;">prototype</span> <span style="color: #339933;">=</span> clone<span style="color: #009900;">&#40;</span>Parent.<span style="color: #660066;">prototype</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">new</span> Child<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    <span style="color: #339933;">|</span>
    v
Child.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    <span style="color: #339933;">|</span>
    v
Parent.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    <span style="color: #339933;">|</span>
    v
Object.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    <span style="color: #339933;">|</span>
    v
   <span style="color: #003366; font-weight: bold;">null</span></pre></div></div>

<p>Using <code>clone</code> method is exactly what person attempts when trying to subclass an array for the first time:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> SubArray<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Take any arguments passed to constructor and add them to an instance</span>
  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">push</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
SubArray.<span style="color: #660066;">prototype</span> <span style="color: #339933;">=</span> clone<span style="color: #009900;">&#40;</span>Array.<span style="color: #660066;">prototype</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> sub <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> SubArray<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> arr <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> sub <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> SubArray<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
arr.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 3</span>
sub.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 0 (in IE&lt;8)</span>
&nbsp;
arr.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
sub.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
&nbsp;
arr<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// [1, 2]</span>
sub<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// [1, 2, 3]</span>
&nbsp;
arr<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">10</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'foo'</span><span style="color: #339933;">;</span>
sub<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">10</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'foo'</span><span style="color: #339933;">;</span>
&nbsp;
arr.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 11</span>
sub.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 2</span></pre></div></div>

<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 &#8211; 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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">var</span> arr <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'x'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'y'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'z'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  arr.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 3 (1 greater than largest index of an array — 2 in this case)</span>
&nbsp;
  arr <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'foo'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  arr.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 1 (1 greater than largest index of an array — 0 in this case)</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> arr <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'x'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'y'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
arr.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 2, as expected</span>
&nbsp;
arr<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'z'</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// add another numeric property (2) larger than the largest existing one (1)</span>
arr.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 3 — length is changed to be 1 greater than (new) largest index (2)</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> arr <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'x'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'y'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'z'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
arr.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
&nbsp;
arr<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// ['x', 'y'] — note how last element (z) is deleted, because being at 2nd index, </span>
     <span style="color: #006600; font-style: italic;">//              it doesn't satisfy criteria of largest index being 1 less than length</span>
&nbsp;
arr.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">;</span>
&nbsp;
arr<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// ['x', 'y'] — &quot;increasing&quot; length doesn't affect numeric properties...</span>
&nbsp;
arr.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;x,y,,&quot; ...but has consequences visible in other cases, such as when using `Array.prototype.join`</span>
&nbsp;
arr.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'z'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
arr<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// ['x', 'y', undefined, undefined, 'z'] — ...or when using `Array.prototype.push`</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> arr <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
arr.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> Math.<span style="color: #660066;">pow</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">32</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// RangeError</span>
&nbsp;
arr.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 0 (length is still 0, as it initially was)</span>
&nbsp;
arr.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> Math.<span style="color: #660066;">pow</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">32</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// set length to maximum allowed value</span>
&nbsp;
arr.<span style="color: #660066;">length</span><span style="color: #339933;">++;</span> <span style="color: #006600; font-style: italic;">// RangeError (when setting length explicitly)</span>
arr.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// RangeError (or when setting length implicitly)</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> SubArray<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">push</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// return array object explicitly</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> sub <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> SubArray<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Object doesn't have 1, 2, 3, as constructor was never called with `this` value referencing returned object</span>
sub<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// []</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// SubArray is not in the prototype chain of returned object</span>
sub <span style="color: #000066; font-weight: bold;">instanceof</span> SubArray<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> arr <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'x'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'y'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
arr.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">5</span><span style="color: #339933;">;</span>
arr.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'z'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 'z' is inserted at 5th index, since that is what the value of &quot;length&quot; is</span>
arr<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// ['x', 'y', undefined, undefined, undefined, 'z']</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> arr <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'x'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'y'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
arr.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;x,y&quot;</span>
arr.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">5</span><span style="color: #339933;">;</span>
arr.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;x,y,,,&quot;</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> arr <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'x'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
arr.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">;</span>
arr.<span style="color: #660066;">concat</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'y'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// ['x', undefined, undefined, 'y']</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> arr <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
arr.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
arr<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// [] — setting length to 0 effectively removes all numeric properties (elements) of an array</span></pre></div></div>

<h3 id="existing_solutions">Existing solutions</h3>
<p>Now that we&#8217;re familiar with the theory, let&#8217;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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> Stack <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #006600; font-style: italic;">// (C) Andrea Giammarchi - Mit Style License</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">function</span> Stack<span style="color: #009900;">&#40;</span>length<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>arguments.<span style="color: #660066;">length</span> <span style="color: #339933;">===</span> <span style="color: #CC0000;">1</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000066; font-weight: bold;">typeof</span> length <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;number&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span> <span style="color: #339933;">&lt;</span> length <span style="color: #339933;">&amp;&amp;</span> length <span style="color: #339933;">===</span> length <span style="color: #339933;">&lt;&lt;</span> <span style="color: #CC0000;">1</span> <span style="color: #339933;">&gt;&gt;</span> <span style="color: #CC0000;">1</span> <span style="color: #339933;">?</span> length <span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>length<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>arguments.<span style="color: #660066;">length</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">push</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">function</span> Array<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  Array.<span style="color: #660066;">prototype</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
  Stack.<span style="color: #660066;">prototype</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #339933;">;</span>
  Stack.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
  Stack.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">toString</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">slice</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>  
&nbsp;
  Stack.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">constructor</span> <span style="color: #339933;">=</span> Stack<span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> Stack<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>It&#8217;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&#8217;t really solve the problem of maintaining relation between <code>length</code> and numeric properties:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> stack <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Stack<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'x'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'y'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
stack.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>           <span style="color: #006600; font-style: italic;">// 2</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// so far so good</span>
&nbsp;
stack.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'z'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
stack.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>           <span style="color: #006600; font-style: italic;">// 3</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// still good</span>
&nbsp;
stack<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'foo'</span><span style="color: #339933;">;</span>
stack.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>           <span style="color: #006600; font-style: italic;">// 3</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// not good anymore (length should have been changed to 4)</span>
&nbsp;
stack.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
stack<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>               <span style="color: #006600; font-style: italic;">// 'z'</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// still not good (element at 2nd index should have been deleted)</span></pre></div></div>

<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 &#8220;borrowed&#8221; from the context of another iframe. </p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// create an &lt;iframe&gt;</span>
<span style="color: #003366; font-weight: bold;">var</span> iframe <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;iframe&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
iframe.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;none&quot;</span><span style="color: #339933;">;</span>
document.<span style="color: #660066;">body</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>iframe<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// write a script into the &amp;lt;iframe&gt; and steal its Array object</span>
frames<span style="color: #009900;">&#91;</span>frames.<span style="color: #660066;">length</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">document</span>.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span>
  <span style="color: #3366CC;">&quot;&lt;script&gt;parent.Array2 = Array;&lt;<span style="color: #000099; font-weight: bold;">\/</span>script&gt;&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// assuming that SubArray was borrowed from another iframe</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> sub <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> SubArray<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
sub <span style="color: #000066; font-weight: bold;">instanceof</span> SubArray<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
sub <span style="color: #000066; font-weight: bold;">instanceof</span> Array<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
sub <span style="color: #000066; font-weight: bold;">instanceof</span> Object<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">new</span> SubArray<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    <span style="color: #339933;">|</span>
    v
<span style="color: #339933;">&lt;</span>another iframe<span style="color: #339933;">&gt;</span>.<span style="color: #660066;">Array</span>.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    <span style="color: #339933;">|</span>
    v
<span style="color: #339933;">&lt;</span>another iframe<span style="color: #339933;">&gt;</span>.<span style="color: #660066;">Object</span>.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    <span style="color: #339933;">|</span>
    v
   <span style="color: #003366; font-weight: bold;">null</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #006600; font-style: italic;">// is this object an array?</span>
&nbsp;
  sub <span style="color: #000066; font-weight: bold;">instanceof</span> Array<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
  sub.<span style="color: #660066;">constructor</span> <span style="color: #339933;">===</span> Array<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span></pre></div></div>

<p>It is, however, still possible to use [[Class]] check (we&#8217;ll talk about [[Class]] later on):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  Object.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">toString</span>.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span>sub<span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">'[object Array]'</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> makeSubArray <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> MAX_SIGNED_INT_VALUE <span style="color: #339933;">=</span> Math.<span style="color: #660066;">pow</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">32</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span>
      hasOwnProperty <span style="color: #339933;">=</span> Object.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">hasOwnProperty</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">function</span> ToUint32<span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> value <span style="color: #339933;">&gt;&gt;&gt;</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">function</span> getMaxIndexProperty<span style="color: #009900;">&#40;</span>object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> maxIndex <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> isValidProperty<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> prop <span style="color: #000066; font-weight: bold;">in</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
      isValidProperty <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>
        String<span style="color: #009900;">&#40;</span>ToUint32<span style="color: #009900;">&#40;</span>prop<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> prop <span style="color: #339933;">&amp;&amp;</span> 
        ToUint32<span style="color: #009900;">&#40;</span>prop<span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> MAX_SIGNED_INT_VALUE <span style="color: #339933;">&amp;&amp;</span> 
        hasOwnProperty.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span>object<span style="color: #339933;">,</span> prop<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isValidProperty <span style="color: #339933;">&amp;&amp;</span> prop <span style="color: #339933;">&gt;</span> maxIndex<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        maxIndex <span style="color: #339933;">=</span> prop<span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> maxIndex<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>methods<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> length <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
    methods <span style="color: #339933;">=</span> methods <span style="color: #339933;">||</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    methods.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
      get<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> maxIndexProperty <span style="color: #339933;">=</span> <span style="color: #339933;">+</span>getMaxIndexProperty<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">return</span> Math.<span style="color: #660066;">max</span><span style="color: #009900;">&#40;</span>length<span style="color: #339933;">,</span> maxIndexProperty <span style="color: #339933;">+</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      set<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> constrainedValue <span style="color: #339933;">=</span> ToUint32<span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>constrainedValue <span style="color: #339933;">!==</span> <span style="color: #339933;">+</span>value<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          <span style="color: #000066; font-weight: bold;">throw</span> <span style="color: #003366; font-weight: bold;">new</span> RangeError<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> constrainedValue<span style="color: #339933;">,</span> len <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          <span style="color: #000066; font-weight: bold;">delete</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        length <span style="color: #339933;">=</span> constrainedValue<span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    methods.<span style="color: #660066;">toString</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
      value<span style="color: #339933;">:</span> Array.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">join</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> Object.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span>Array.<span style="color: #660066;">prototype</span><span style="color: #339933;">,</span> methods<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> subMethods <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
  last<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    value<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#91;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">length</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> sub <span style="color: #339933;">=</span> makeSubArray<span style="color: #009900;">&#40;</span>subMethods<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> sub2 <span style="color: #339933;">=</span> makeSubArray<span style="color: #009900;">&#40;</span>subMethods<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// etc.</span></pre></div></div>

<p>We can also hide this factory method behind a constructor, to make it similar to <code>Array</code>&#8217;s one:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> SubArray <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> methods <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> 
    last<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> 
      value<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#91;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">length</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span> 
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> arr <span style="color: #339933;">=</span> makeSubArray<span style="color: #009900;">&#40;</span>methods<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>arguments.<span style="color: #660066;">length</span> <span style="color: #339933;">===</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      arr.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> arguments<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
      arr.<span style="color: #660066;">push</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>arr<span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> arr<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>And then use it as you would use regular <code>Array</code> constructor:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> sub <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> SubArray<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
sub.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 3</span>
sub<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// [1, 2, 3]</span>
&nbsp;
sub.<span style="color: #660066;">length</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
sub<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// [1]</span>
&nbsp;
sub<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">10</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'x'</span><span style="color: #339933;">;</span>
sub.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// assuming that `sub` is a pseudo-array</span>
Object.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">toString</span>.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span>sub<span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">'[object Array]'</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// assuming that `sub` is a pseudo-array</span>
someFunction.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> sub<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// TypeError</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// array ([[Class]] == &quot;Array&quot;)</span>
<span style="color: #003366; font-weight: bold;">var</span> arr <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'x'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'y'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// object with numeric properties ([[Class]] == &quot;Object&quot;)</span>
<span style="color: #003366; font-weight: bold;">var</span> obj <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #3366CC;">'0'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'x'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'1'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'y'</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">concat</span><span style="color: #009900;">&#40;</span>arr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// [1, 2, 3, 'x', 'y']</span>
<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">concat</span><span style="color: #009900;">&#40;</span>obj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// [1, 2, 3, { '0': 'x', '1': 'y' }]</span></pre></div></div>

<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&#8217;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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> makeSubArray<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> arr <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  arr.<span style="color: #660066;">push</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>arr<span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  arr.<span style="color: #660066;">last</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#91;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">length</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> arr<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> sub <span style="color: #339933;">=</span> makeSubArray<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
sub <span style="color: #000066; font-weight: bold;">instanceof</span> Array<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
&nbsp;
sub.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 3</span>
sub.<span style="color: #660066;">last</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 3</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> SubArray<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
SubArray.<span style="color: #660066;">prototype</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #339933;">;</span>
SubArray.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">last</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#91;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">length</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> makeSubArray<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> arr <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  arr.<span style="color: #660066;">push</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>arr<span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  arr.__proto__ <span style="color: #339933;">=</span> SubArray.<span style="color: #660066;">prototype</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> arr<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">new</span> SubArray<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    <span style="color: #339933;">|</span>
    v
SubArray.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    <span style="color: #339933;">|</span>
    v
Array.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    <span style="color: #339933;">|</span>
    v
Object.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    <span style="color: #339933;">|</span>
    v
   <span style="color: #003366; font-weight: bold;">null</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> SubArray<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> arr <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  arr.<span style="color: #660066;">push</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>arr<span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  arr.__proto__ <span style="color: #339933;">=</span> SubArray.<span style="color: #660066;">prototype</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> arr<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
SubArray.<span style="color: #660066;">prototype</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #339933;">;</span>
SubArray.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">last</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#91;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">length</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> sub <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> SubArray<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
sub <span style="color: #000066; font-weight: bold;">instanceof</span> SubArray<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
sub <span style="color: #000066; font-weight: bold;">instanceof</span> Array<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span></pre></div></div>

<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="tweetmeme_button" style="float: right; margin-left: 30px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fperfectionkills.com%2Fhow-ecmascript-5-still-does-not-allow-to-subclass-an-array%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fperfectionkills.com%2Fhow-ecmascript-5-still-does-not-allow-to-subclass-an-array%2F&amp;source=kangax&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8628792cef804c13af5f8ae4e1ba60e3" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>JScript and DOM changes in IE9 preview 3</title>
		<link>http://perfectionkills.com/jscript-and-dom-changes-in-ie9-preview-3/</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[[[Class]]]]></category>
		<category><![CDATA[isArray]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[strict-mode]]></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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  Object.<span style="color: #660066;">getPrototypeOf</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">body</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// null</span>
  Object.<span style="color: #660066;">getPrototypeOf</span><span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// null</span>
  Object.<span style="color: #660066;">getPrototypeOf</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">alert</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// null</span>
  Object.<span style="color: #660066;">getPrototypeOf</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">childNodes</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// null</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  Object.<span style="color: #660066;">getPrototypeOf</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">body</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> HTMLBodyElement.<span style="color: #660066;">prototype</span><span style="color: #339933;">;</span>
  Object.<span style="color: #660066;">getPrototypeOf</span><span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> HTMLDocument.<span style="color: #660066;">prototype</span><span style="color: #339933;">;</span>
  Object.<span style="color: #660066;">getPrototypeOf</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">alert</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #003366; font-weight: bold;">Function</span>.<span style="color: #660066;">prototype</span><span style="color: #339933;">;</span>
  Object.<span style="color: #660066;">getPrototypeOf</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">childNodes</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> NodeList.<span style="color: #660066;">prototype</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">var</span> bound <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> f<span style="color: #009900;">&#40;</span>x<span style="color: #339933;">,</span> y<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> x<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  bound <span style="color: #339933;">+</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;function(){ [native code] }&quot;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// compare to</span>
&nbsp;
  <span style="color: #000066;">alert</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;function alert(){ [native code] }&quot;</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">function</span> isArray<span style="color: #009900;">&#40;</span>o<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> Object.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">toString</span>.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span>o<span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;[object Array]&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">var</span> f <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> g<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> f <span style="color: #339933;">===</span> g<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> g<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;undefined&quot;</span>
&nbsp;
  f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span></pre></div></div>

<p><code>arguments</code>&#8217; [[Class]] is now an &#8220;Arguments&#8221;, just like ES5 specifies it:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">var</span> args <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> arguments<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  Object.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">toString</span>.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span>args<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;[object Arguments]&quot;</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #000066;">alert</span> <span style="color: #000066; font-weight: bold;">instanceof</span> Object<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> <span style="color: #000066;">alert</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;object&quot;</span>
  <span style="color: #000066;">alert</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// undefined</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #000066;">alert</span>.<span style="color: #660066;">toString</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// undefined</span>
  <span style="color: #000066;">alert</span>.<span style="color: #660066;">constructor</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// undefined</span>
  <span style="color: #000066;">alert</span>.<span style="color: #660066;">hasOwnProperty</span><span style="color: #339933;">;</span> undefined</pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #000066;">alert</span> <span style="color: #000066; font-weight: bold;">instanceof</span> <span style="color: #003366; font-weight: bold;">Function</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
  document.<span style="color: #660066;">createElement</span> <span style="color: #000066; font-weight: bold;">instanceof</span> <span style="color: #003366; font-weight: bold;">Function</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
&nbsp;
  <span style="color: #000066;">alert</span>.<span style="color: #660066;">call</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// undefined</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #000066; font-weight: bold;">typeof</span> document.<span style="color: #660066;">createElement</span>.<span style="color: #660066;">call</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;function&quot;</span>
  document.<span style="color: #660066;">createElement</span>.<span style="color: #660066;">call</span> <span style="color: #339933;">===</span> <span style="color: #003366; font-weight: bold;">Function</span>.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">call</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  Object.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">toString</span>.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">alert</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;[object Object]&quot;</span>
  Object.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">toString</span>.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;[object Object]&quot;</span></pre></div></div>

<p>IE9pre3 still messes up DOM objects&#8217; attributes and properties, although not as badly as earlier versions:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">var</span> el <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'p'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  el.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'x'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'y'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  el.<span style="color: #660066;">x</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 'y'</span>
&nbsp;
  el.<span style="color: #660066;">foobarbaz</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'moo'</span><span style="color: #339933;">;</span>
  el.<span style="color: #660066;">hasAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'foobarbaz'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
  el.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'foobarbaz'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 'moo'</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #000066; font-weight: bold;">typeof</span> Option.<span style="color: #660066;">create</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;string&quot;</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> Image.<span style="color: #660066;">create</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;string&quot;</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> document.<span style="color: #660066;">childNodes</span>.<span style="color: #000066; font-weight: bold;">item</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;string&quot;</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #339933;">&lt;</span>div id<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;foo&quot;</span><span style="color: #339933;">&gt;&lt;/</span>div<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;</span>a <span style="color: #000066;">name</span><span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;bar&quot;</span><span style="color: #339933;">&gt;&lt;/</span>a<span style="color: #339933;">&gt;</span>
  ...
  <span style="color: #339933;">&lt;</span>script<span style="color: #339933;">&gt;</span>
    foo <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #009966; font-style: italic;">/* ... */</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// Error</span>
    bar <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #009966; font-style: italic;">/* ... */</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// no Error</span>
  <span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    v
  HTMLDivElement.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    v
  Element.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    v
  <span style="color: #003366; font-weight: bold;">null</span></pre></div></div>

<p>&#8230;rather than what can be seen in almost all other modern browsers:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    v
  HTMLDivElement.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    v
  HTMLElement.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    v
  Element.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    v
  Node.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    v
  Object.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">|</span>
    <span style="color: #339933;">|</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#91;</span>Prototype<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>
    v
  <span style="color: #003366; font-weight: bold;">null</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  document.<span style="color: #660066;">defaultView</span>.<span style="color: #660066;">getComputedStyle</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// null</span>
  <span style="color: #3366CC;">'getComputedStyle'</span> <span style="color: #000066; font-weight: bold;">in</span> document.<span style="color: #660066;">defaultView</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span></pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  Array.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">slice</span>.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">childNodes</span><span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">instanceof</span> Array<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span></pre></div></div>

<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="tweetmeme_button" style="float: right; margin-left: 30px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fperfectionkills.com%2Fjscript-and-dom-changes-in-ie9-preview-3%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fperfectionkills.com%2Fjscript-and-dom-changes-in-ie9-preview-3%2F&amp;source=kangax&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8628792cef804c13af5f8ae4e1ba60e3" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/jscript-and-dom-changes-in-ie9-preview-3/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Tag is not an element. Or is it?</title>
		<link>http://perfectionkills.com/tag-is-not-an-element-or-is-it/</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
If you [...]]]></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>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">  &lt;p&gt;foo bar
&nbsp;
  &lt;tr&gt;
    &lt;td&gt;baz
    &lt;td&gt;qux
  &lt;/tr&gt;</pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">  &lt;html&gt;
    &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.  --&gt;
    &lt;body&gt;
    ...
    &lt;/body&gt;
  &lt;/html&gt;</pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">  &lt;p&gt;
    &lt;img ...&gt; &lt;!-- IMG tag is inserted after a start P tag --&gt;
    ...
  &lt;/p&gt;</pre></div></div>

<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>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">  &lt;p&gt;
    ...
  &lt;/p&gt;
  &lt;img ...&gt; &lt;!-- IMG tag is inserted after an end P tag --&gt;</pre></div></div>

<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="tweetmeme_button" style="float: right; margin-left: 30px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fperfectionkills.com%2Ftag-is-not-an-element-or-is-it%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fperfectionkills.com%2Ftag-is-not-an-element-or-is-it%2F&amp;source=kangax&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8628792cef804c13af5f8ae4e1ba60e3" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/tag-is-not-an-element-or-is-it/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>What&#8217;s wrong with extending the DOM</title>
		<link>http://perfectionkills.com/whats-wrong-with-extending-the-dom/</link>
		<comments>http://perfectionkills.com/whats-wrong-with-extending-the-dom/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 19:05:50 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[DOMLint]]></category>
		<category><![CDATA[ECMA-262]]></category>
		<category><![CDATA[annoyances]]></category>
		<category><![CDATA[don'ts]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=205</guid>
		<description><![CDATA[I was recently surprised to find out how little the topic of DOM extensions is covered on the web. What&#8217;s disturbing is that downsides of this seemingly useful practice don&#8217;t seem to be well known, except in certain secluded circles. The lack of information could well explain why there are scripts and libraries built today [...]]]></description>
			<content:encoded><![CDATA[<p>I was recently surprised to find out how little the topic of DOM extensions is covered on the web. What&#8217;s disturbing is that <strong>downsides of this seemingly useful practice</strong> don&#8217;t seem to be well known, except in <a href="http://groups.google.com/group/comp.lang.javascript/topics">certain secluded circles</a>. The lack of information could well explain why there are scripts and libraries <strong>built today</strong> that still fall into this trap. I&#8217;d like to explain why extending DOM is <strong>generally a bad idea</strong>, by showing some of the problems associated with it. We&#8217;ll also look at possible alternatives to this harmful exercise.</p>
<p>But first of all, what exactly is DOM extension? And how does it all work?</p>
<h3 id="how_dom_extension_works">How DOM extension works</h3>
<p>DOM extension is simply the process of adding custom methods/properties to DOM objects. Custom properties are those that don&#8217;t exist in a particular implementation. And what are the DOM objects? These are host objects implementing <code>Element</code>, <code>Event</code>, <code>Document</code>, or any of dozens of other DOM interfaces. During extension, methods/properties can be added to objects directly, or to their prototypes (but only in environments that have proper support for it).</p>
<p>The most commonly extended objects are probably DOM elements (those that implement <a href="http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-745549614"><code>Element</code> interface</a>), popularized by Javascript libraries like Prototype and Mootools. Event objects (those that implement <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event"><code>Event</code> interface</a>), and documents (<a href="http://www.w3.org/TR/DOM-Level-2-Core/core.html#i-Document"><code>Document</code> interface</a>) are often extended as well.</p>
<p>In environment that exposes prototype of Element objects, an example of DOM extension would look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  Element.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">hide</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'none'</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  ...
  <span style="color: #003366; font-weight: bold;">var</span> element <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'p'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  element.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// ''</span>
  element.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  element.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 'none'</span></pre></div></div>

<p>As you can see, &#8220;hide&#8221; function is first assigned to a <code>hide</code> property of <code>Element.prototype</code>. It is then invoked directly on an element, and element&#8217;s &#8220;display&#8221; style is set to &#8220;none&#8221;.</p>
<p>The reason this &#8220;works&#8221; is because object referred to by <code>Element.prototype</code> is actually one of the objects in <strong>prototype chain of P element</strong>. When <code>hide</code> property is resolved on it, it&#8217;s searched throughout the prototype chain until found on this <code>Element.prototype</code> object.</p>
<p>In fact, if we were to examine prototype chain of P element in some of the modern browsers, it would usually look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #006600; font-style: italic;">// &quot;^&quot; denotes connection between objects in prototype chain</span>
&nbsp;
  document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'p'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #339933;">^</span>
  HTMLParagraphElement.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">^</span>
  HTMLElement.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">^</span>
  Element.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">^</span>
  Node.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">^</span>
  Object.<span style="color: #660066;">prototype</span>
    <span style="color: #339933;">^</span>
  <span style="color: #003366; font-weight: bold;">null</span></pre></div></div>

<p>Note how the nearest ancestor in the prototype chain of <code>P</code> element is object referred to by <code>HTMLParagraphElement.prototype</code>. This is an object specific to type of an element. For <code>P</code> element, it&#8217;s <code>HTMLParagraphElement.prototype</code>; for <code>DIV</code> element, it&#8217;s <code>HTMLDivElement.prototype</code>; for <code>A</code> element, it&#8217;s <code>HTMLAnchorElement.prototype</code>, and so on.</p>
<p>But why such strange names, you might ask?</p>
<p>These names actually correspond to <a href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-798055546">interfaces defined in DOM Level 2 HTML Specification</a>. That same specification also defines inheritance between those interfaces. It says, for example, that <cite>&#8220;&#8230; HTMLParagraphElement interface have all properties and functions of the HTMLElement interface &#8230;&#8221;</cite> (<a href="http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html">source</a>) and that <cite>&#8220;&#8230; HTMLElement interface have all properties and functions of the Element interface &#8230;&#8221;</cite> (<a href="http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html">source</a>), and so on.</p>
<p>Quite obviously, if we were to create a property on &#8220;prototype object&#8221; of paragraph element, that property would not be available on, say, anchor element:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  HTMLParagraphElement.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">hide</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'none'</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  ...
  <span style="color: #000066; font-weight: bold;">typeof</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'a'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;undefined&quot;</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'p'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;function&quot;</span></pre></div></div>

<p>This is because anchor element&#8217;s prototype chain never includes object refered to by <code>HTMLParagraphElement.prototype</code>, but instead includes that referred to by <code>HTMLAnchorElement.prototype</code>. To &#8220;fix&#8221; this, we can assign to property of object positioned further in the prototype chain, such as that referred to by <code>HTMLElement.prototype</code>, <code>Element.prototype</code> or <code>Node.prototype</code>.</p>
<p>Similarly, creating a property on <code>Element.prototype</code> would not make it available on all nodes, but only on nodes of element type. If we wanted to have property on all nodes (e.g. text nodes, comment nodes, etc.), we would need to assign to property of <code>Node.prototype</code> instead. And speaking of text and comment nodes, this is how interface inheritance usually looks for them:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  document.<span style="color: #660066;">createTextNode</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &lt; Text.prototype &lt; CharacterData.prototype &lt; Node.prototype</span>
  document.<span style="color: #660066;">createComment</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'bar'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &lt; Comment.prototype &lt; CharacterData.prototype &lt; Node.prototype</span></pre></div></div>

<p>Now, it&#8217;s important to understand that <strong>exposure of these DOM object prototypes is not guaranteed</strong>. DOM Level 2 specification merely defines interfaces, and inheritance between those interfaces. It does not state that there should exist global <code>Element</code> property, referencing object that&#8217;s a prototype of all objects implementing <code>Element</code> interface. Neither does it state that there should exist global <code>Node</code> property, referencing object that&#8217;s a prototype of all objects implementing <code>Node</code> interface.</p>
<p>Internet Explorer 7 (and below) is an example of such environment; it does not expose global <code>Node</code>, <code>Element</code>, <code>HTMLElement</code>, <code>HTMLParagraphElement</code>, or other properties. Another such browser is Safari 2.x (and most likely Safari 1.x).</p>
<p>So what can we do in environments that <strong>don&#8217;t expose these global &#8220;prototype&#8221; objects</strong>? A workaround is to extend DOM objects directly:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">var</span> element <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'p'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  ...
  <span style="color: #660066;">element</span>.<span style="color: #660066;">hide</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'none'</span><span style="color: #339933;">;</span> 
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  ...
  <span style="color: #660066;">element</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// ''</span>
  element.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  element.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 'none'</span></pre></div></div>

<h3 id="what_went_wrong">What went wrong?</h3>
<p>Being able to extend DOM elements through prototype objects sounds amazing. We are taking advantage of Javascript prototypal nature, and scripting DOM becomes very object-oriented. In fact, DOM extension seemed so temptingly useful that few years ago, <a href="http://prototypejs.org/">Prototype Javascript library</a> made it an essential part of its architecture. But what hides behind seemingly innocuous practice is a huge load of trouble. As we&#8217;ll see in a moment, when it comes to cross-browser scripting, the downsides of this approach far outweigh any benefits. <strong>DOM extension is one of the biggest mistakes Prototype.js has ever done</strong>.</p>
<p>So what are these problems?</p>
<h3 id="lack_of_specification">Lack of specification</h3>
<p>As I have already mentioned, exposure of &#8220;prototype objects&#8221; is not part of any specification. DOM Level 2 merely defines interfaces and their inheritance relations. In order for implementation to conform to DOM Level 2 fully, there&#8217;s no need to expose those global <code>Node</code>, <code>Element</code>, <code>HTMLElement</code>, etc. objects. Neither is there a requirement to expose them in any other way. Given that there&#8217;s always a possibility to extend DOM objects manually, this doesn&#8217;t seem like a big issue. But the truth is that manual extension is a rather slow and inconvenient process (as we will see shortly). And the fact that fast, &#8220;prototype object&#8221; -based extension is merely somewhat of a de-facto standard among few browsers, makes this practice unreliable when it comes to future adoption or portability across non-convential platforms (e.g. mobile devices).</p>
<h3 id="host_objects_have_no_rules">Host objects have no rules</h3>
<p>Next problem with DOM extension is that <strong>DOM objects are host objects</strong>, and host objects are the worst bunch. By specification (ECMA-262 3rd. ed), host objects are allowed to do things, no other objects can even dream of. To quote relevant section <sup>[<a href="http://bclary.com/2004/11/07/#a-8.6.2">8.6.2</a>]</sup>:</p>
<p><cite style="display: block; margin-left: 2em;">Host objects may implement these internal methods with any implementation-dependent behaviour, or it may be that a host object implements only some internal methods and not others.</cite></p>
<p>The internal methods specification talks about are [[Get]], [[Put]], [[Delete]], etc. Note how it says that <strong>internal methods behavior is implementation-dependent</strong>. What this means is that it&#8217;s absolutely normal for host object to throw error on invocation of, say, [[Get]] method. And unfortunatey, this isn&#8217;t just a theory. In Internet Explorer, we can easily observe exactly this—an example of host object [[Get]] throwing error:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'p'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">offsetParent</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;Unspecified error.&quot;</span>
  <span style="color: #003366; font-weight: bold;">new</span> ActiveXObject<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;MSXML2.XMLHTTP&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">send</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;Object doesn't support this property or method&quot;</span></pre></div></div>

<p>Extending DOM objects is kind of like walking in a minefield. By definition, you are working with something that&#8217;s allowed to behave in unpredictable and completely erratic way. And not only things can blow up; there&#8217;s also a possibility of silent failures, which is even worse scenario. An example of erratic behavior is <code>applet</code>, <code>object</code> and <code>embed</code> elements, which in certain cases <a href="http://github.com/jquery/jquery/commit/59802928566b6be3a66d65e77c2418fff37e6f5f">throw errors on assignment of properties</a>. Similar disaster happens with XML nodes:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">var</span> xmlDoc <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> ActiveXObject<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Microsoft.XMLDOM&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  xmlDoc.<span style="color: #660066;">loadXML</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;foo&gt;bar&lt;/foo&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  xmlDoc.<span style="color: #660066;">firstChild</span>.<span style="color: #660066;">foo</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'bar'</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;Object doesn't support this property or method&quot;</span></pre></div></div>

<p>There are <a href="http://jibbering.com/faq/notes/code-guidelines/#hostObjects">other cases of failures in IE</a>, such as <code>document.styleSheets[99999]</code> throwing &#8220;Invalid procedure call or argument&#8221; or <code>document.createElement('p').filters</code> throwing &#8220;Member not found.&#8221; exceptions. But not only MSHTML DOM is the problem. Trying to overwrite &#8220;target&#8221; property of <code>event</code> object in Mozilla throws TypeError, complaining that property has only a getter (meaning that it&#8217;s readonly and can not be set). Doing same thing in WebKit, results in silent failure, where &#8220;target&#8221; continues to refer to original object after assignment.</p>
<p>When creating API for working with event objects, there&#8217;s now a need to <strong>consider all of these readonly properties</strong>, instead of focusing on concise and descriptive names.</p>
<p>A good rule of thumb is to <strong>avoid touching host objects</strong> as much as possible. Trying to base architecture on something that—by definition—can behave so sporadically is hardly a good idea.</p>
<h3 id="chance_of_collisions">Chance of collisions</h3>
<p>API based on DOM element extensions is <strong>hard to scale</strong>. It&#8217;s hard to scale for developers of the library—when adding new or changing core API methods, and for library users—when adding domain-specific extensions. The root of the issue is a <strong>likely chance of collisions</strong>. DOM implementations in popular browsers usually all have properietary API&#8217;s. What&#8217;s worse is that these API&#8217;s are not static, but constantly change as new browser versions come out. Some parts get deprecated; others are added or modified. As a result, set of properties and methods present on DOM objects is somewhat of a moving target. </p>
<p>Given huge amount of environments in use today, it becomes impossible to tell if certain property is not already part of some DOM. And if it is, can it be overwritten? Or will it throw error when attempting to do so? Remember that it&#8217;s a host object! And if we can quietly overwrite it, how would it affect other parts of DOM? Would everything still work as expected? If everything is fine in one version of such browser, is there a guarantee that next version doesn&#8217;t introduce same-named property? The list of questions goes on.</p>
<p>Some examples of proprietary extensions that broke Prototype are <a href="http://dev.rubyonrails.org/ticket/10189">wrap property on textareas in IE</a> (colliding with <a href="http://www.prototypejs.org/api/element/wrap">Element#wrap method</a>), and <a href="http://dev.rubyonrails.org/ticket/11251"><code>select</code> method on form control elements in Opera</a> (colliding with <a href="http://www.prototypejs.org/api/element/select">Element#select method</a>). Even though both of these cases are documented, having to remember these little exceptions is annoying.</p>
<p>Proprietary extensions are not the only problem. HTML5 brings new methods and properties to the table. And most of the popular browsers have already started implementing them. At some point, <a href="http://www.whatwg.org/specs/web-forms/current-work">WebForms</a> defined <code>replace</code> property on input elements, which Opera decided to add to their browser. And once again, <a href="http://dev.rubyonrails.org/ticket/9261">it broke Prototype</a>, due to conflict with <a href="http://www.prototypejs.org/api/element/replace">Element#replace</a> method.</p>
<p>But wait, there&#8217;s more! </p>
<p>Due to long-standing DOM Level 0 tradition, there&#8217;s this &#8220;convenient&#8221; way to <a href="http://yura.thinkweb2.com/domlint/">access form controls off of form elements</a>, simply by their name. What this means is that instead of using standard <code>elements</code> collection, you can access form control like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">  &lt;form action=&quot;&quot;&gt;
    &lt;input name=&quot;foo&quot;&gt;
  &lt;/form&gt;
  ...
  &lt;script type=&quot;text/javascript&quot;&gt;
    document.forms[0].foo; // non-standard access
    // compare to
    document.forms[0].elements.foo; // standard access
  &lt;/script&gt;</pre></div></div>

<p>So, say you extend form elements with <code>login</code> method, which for example checks validation and submits login form. If you also happen to have form control with &#8220;login&#8221; name (which is pretty likely, if you ask me), what happens next is not pretty:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">  &lt;form action=&quot;&quot;&gt;
    &lt;input name=&quot;login&quot;&gt;
    ...
  &lt;/form&gt;
  ...
  &lt;script type=&quot;text/javascript&quot;&gt;
    HTMLFormElement.prototype.login = function(){ 
      return 'logging in'; 
    };
    ...
    $(myForm).login(); // boom!
    // $(myForm).login references input element, not `login` method
  &lt;/script&gt;</pre></div></div>

<p><strong>Every named form control shadows properties inherited through prototype chain</strong>. The chance of collisions and unexpected errors on form elements is even higher.</p>
<p>Situation is somewhat similar with named <code>form</code> elements, where they can be <strong>accessed directly off <code>document</code></strong> by their names:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">  &lt;form name=&quot;foo&quot;&gt;
    ...
  &lt;/form&gt;
  ...
  &lt;script type=&quot;text/javascript&quot;&gt;
    document.foo; // [object HTMLFormElement]
  &lt;/script&gt;</pre></div></div>

<p>When extending document objects, there&#8217;s now an additional risk of form names conflicting with extensions. And what if script is running in legacy applications with tons of rusty HTML, where changing/removing such names is not a trivial task?</p>
<p>Employing some kind of <strong>prefixing strategy</strong> can alleviate the problem. But will probably also bring extra noise.</p>
<p><a href="http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/">Not modifying objects you don&#8217;t own</a> is an ultimate recipe for avoiding collisions. Breaking this rule already got Prototype into trouble, when it <a href="http://ejohn.org/blog/getelementsbyclassname-pre-prototype-16/">overwrote <code>document.getElementsByClassName</code></a> with own, custom implementation. Following it also means playing nice with other scripts, running in the same environment&#8212;no matter if they modify DOM objects or not.</p>
<h3 id="performance_overhead">Performance overhead</h3>
<p>As we&#8217;ve seen before, browsers that don&#8217;t support element extensions&#8212;like IE 6, 7, Safari 2.x, etc.&#8212;require manual object extension. The problem is that manual extension is slow, inconvenient and doesn&#8217;t scale. It&#8217;s slow because object needs to be extended with what&#8217;s often a large number of methods/properties. And ironically, these browsers are the slowest ones around. It&#8217;s inconvenient because object needs to be <strong>first extended</strong> in order to be operated on. So instead of  <code>document.createElement('p').hide()</code>, you would need to do something like <code>$(document.createElement('p')).hide()</code>. This, by the way, is one of the most common stumbing blocks for beginners of Prototype. Finally, manual extension doesn&#8217;t scale well because adding API methods affects performance pretty much linearly. If there&#8217;s 100 methods on <code>Element.prototype</code>, there has to be 100 assignments made to an element in question; if there&#8217;s 200 methods, there has to be 200 assignments made to an element, and so on.</p>
<p>Another performance hit is with event objects. Prototype follows similar approach with events and extends them with a certain set of methods. Unfortunately, some events in browsers&#8212;mousemove, mouseover, mouseout, resize, to name few&#8212;can fire literally dozens of times per second. Extending each one of them is an incredibly expensive process. And what for? Just to invoke what could be a single method on event obejct?</p>
<p>Finally, once you start extending elements, library API most likely needs to <strong>return <em>extended</em> elements everywhere</strong>. As a result, querying methods like <code>$$</code> could end up extending every single element in a query. It&#8217;s easy to imagine performance overead of such process, when we&#8217;re talking about hundreds or thousands of elements.</p>
<h3 id="ie_dom_is_a_mess">IE DOM is a mess</h3>
<p>As shown in previous section, manual DOM extension is a mess. But <strong>manual DOM extension in IE is even worse</strong>, and here&#8217;s why.</p>
<p>We all know that in IE, circular references between host and native objects leak, and are best avoided. But adding methods to DOM elements is a first step towards creation of such circular references. And since older versions of IE don&#8217;t expose &#8220;object prototypes&#8221;, there&#8217;s not much to do but extend elements directly. Circular references and leaks are almost inevitable. And in fact, Prototype suffered from them for most of its lifetime.</p>
<p>Another problem is the way IE DOM maps properties and attributes to each other. The fact that attributes are in the same namespace as properties, increases chance of collisions and all kinds of unexpected inconsistencies. What happens if element has custom &#8220;show&#8221; attribute and is then extended by Prototype. You&#8217;ll be surprised, but show &#8220;attribute&#8221; would get overwritten by Prototype&#8217;s <code>Element#show</code> method. <code>extendedElement.getAttribute('show')</code> would return a reference to a function, not the value of &#8220;show&#8221; attribute. Similarly, <code>extendedElement.hasAttribute('hide')</code> would say &#8220;true&#8221;, even if there was never custom &#8220;hide&#8221; attribute on an element. Note that IE&lt;8 lacks <code>hasAttribute</code>, but we could still see attribute/property conflict: <code>typeof extendedElement.attributes['show'] != "undefined"</code>.</p>
<p>Finally, one of the lesser-known downsides is the fact that adding properties to DOM elements causes reflow in IE, so mere extension of element becomes a quite expensive operation. This actually makes sense, given the deficient mapping of attributes and properties in its DOM.</p>
<h3 id="bonus_browser_bugs">Bonus: browser bugs</h3>
<p>If everything we&#8217;ve been over so far is not enough (in which case, you&#8217;re probably a masochist), here&#8217;s a couple more bugs to top it all of.</p>
<p>In some versions of Safari 3.x, there&#8217;s a bug where navigating to a previous page via back button <a href="http://webkit.org/blog/427/webkit-page-cache-i-the-basics/#comment-25207">wipes off all host object extensions</a>. Unfortunately, the bug is undetectable, so to work around the issue, Prototype has to do something horrible. It sniffs browser for that version of WebKit, and explicitly disables bfcache by attaching &#8220;unload&#8221; event listener to <code>window</code>. Disabled bfcache means that <strong>browser has to re-fetch page</strong> when navigating via back/forward buttons, instead of restoring page from the cached state.</p>
<p>Another bug is with <code>HTMLObjectElement.prototype</code> and <code>HTMLAppletElement.prototype</code> in IE8, and the way object and applet elements <strong>don&#8217;t inherit from those prototype objects</strong>. You can assign to a property of <code>HTMLObjectElement.prototype</code>, but that property is never &#8220;resolved&#8221; on object element. Ditto for applets. As a result, those elements always have to be extended manually, which is another overhead.</p>
<p>IE8 also <a href="http://msdn.microsoft.com/en-us/library/dd282900%28VS.85%29.aspxs">exposes only a subset of prototype objects</a>, when compared to other popular implementations. For example, there&#8217;s <code>HTMLParagraphElement.prototype</code> (as well as other type-specific ones), and <code>Element.prototype</code>, but no <code>HTMLElement</code> (and so <code>HTMLElement.prototype</code>) or <code>Node</code> (and so <code>Node.prototype</code>). <code>Element.prototype</code> in IE8 also doesn&#8217;t inherit from <code>Object.prototype</code>. These are not bugs, per se, but is something to keep in mind nevertheless: there&#8217;s nothing good about trying to extend non-existent <code>Node</code>, for example.</p>
<h3 id="wrappers_to_the_rescue">Wrappers to the rescue</h3>
<p>One of the most common alternatives to this whole mess of DOM extension is <strong>object wrappers</strong>. This is the approach jQuery has taken from the start, and few other libraries followed later on. The idea is simple. Instead of extending elements or events directly, create a wrapper around them, and delegate methods accordingly. No collisions, no need to deal with host objects madness, easier to manage leaks and operate in dysfunctional MSHTML DOM, better performance, saner maintenance and painless scaling.</p>
<p>And you still avoid procedural approach.</p>
<h3 id="prototype_20">Prototype 2.0</h3>
<p>The good news is that Prototype mistake is something that&#8217;s <strong>going away in the next major version of the library</strong>. As far as I&#8217;m concerned, all core developers understand the problems mentioned above, and that wrapper approach is the saner way to move forward. I&#8217;m not sure what the plans are in other DOM-extending libraries like Mootools. From what I can see they are already using wrappers with events, but still extend elements. I&#8217;m certinaly hoping they move away from this madness in a near future.</p>
<h3 id="controlled_environments">Controlled environments</h3>
<p>So far we looked at DOM extension from the point of view of <strong>cross-browser scripting library</strong>. In that context, it&#8217;s clear how troublesome this idea really is. But what about controlled environments? When script is only run in one or two environments, such as those based on Gecko, WebKit or any other modern non-MSHTML DOM. Perhaps it&#8217;s an intranet application, that&#8217;s accessed through certain browsers. Or a desktop, WebKit-based app.</p>
<p>In that case, <strong>situtation is definitly better</strong>. Let&#8217;s look at the points listed above.</p>
<p>Lack of specification <strong>becomes somewhat irrelevant</strong>, as there&#8217;s no need to worry about compatibility with other platforms, or future editions. Most of the non-MSHTML DOM environments expose DOM object prototypes for quite a while, and are unlikely to drop it in a near future. There&#8217;s still a possibility for change, however.</p>
<p>Point about host objects unreliability also <strong>loses its weight</strong>, since host objects in Gecko or WebKit -based DOMs are much, much saner than those in MSHTML DOM. But they are still host objects, and so should be treated with care. Besides, there are readonly properties covered before, which could easily cripple the flexibility of API.</p>
<p>The point about collisions <strong>still holds weight</strong>. These environments support non-standard form controls access, have proprietary API, and are constantly implementing new HTML5 features. Modifying objects you don&#8217;t own is still a wicked idea and can lead to hard-to-find bugs and inconsistencies.</p>
<p>Performance overhead is <strong>practically non-existent</strong>, as these DOM support prototype-based DOM extension. Performance can actually be even better, comparing to, say, wrappers approach, as there&#8217;s no need to create any additional objects in order to invoke methods (or access properties) off DOM objects.</p>
<p>Extending DOM in controlled environment sure seems like a perfectly healthy thing to do. But even though the main problem is that with collisions, I would still advise to <strong>employ wrappers instead</strong>. It&#8217;s a safer way to move forward, and will save you from maintenance overhead in the future.</p>
<h3 id="afterword">Afterword</h3>
<p>Hopefuly, you can now clearly see all the truth behind what looks like an elegant approach. Next time you design a Javascript framework, just <strong>say no to DOM extensions</strong>. Say no, and save yourself from all the trouble of maintaining a cumbersome API and suffering unnecessary performance overheads. If on the other hand, you&#8217;re considering to employ Javascript library that extends DOM, stop for a second, and ask yourself if you&#8217;re willing to take a risk. Is ellusive convenience of DOM extension really worth all the trouble?</p>
<div class="tweetmeme_button" style="float: right; margin-left: 30px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fperfectionkills.com%2Fwhats-wrong-with-extending-the-dom%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fperfectionkills.com%2Fwhats-wrong-with-extending-the-dom%2F&amp;source=kangax&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8628792cef804c13af5f8ae4e1ba60e3" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/whats-wrong-with-extending-the-dom/feed/</wfw:commentRss>
		<slash:comments>39</slash:comments>
		</item>
		<item>
		<title>Experimenting with html minifier</title>
		<link>http://perfectionkills.com/experimenting-with-html-minifier/</link>
		<comments>http://perfectionkills.com/experimenting-with-html-minifier/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 17:48:35 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[html]]></category>
		<category><![CDATA[optimizations]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=169</guid>
		<description><![CDATA[
  #experimenting_with_html_minifier .footnotes { font-size: 0.85em; }
  #experimenting_with_html_minifier ul ul { margin: 0.5em 0 0 0; }
  #experimenting_with_html_minifier ul ul li { margin-bottom: 0.25em; }
  #experimenting_with_html_minifier ul li { margin-bottom: 1em; }
  #experimenting_with_html_minifier h4 { font-size: 1em; }




      How it works


     [...]]]></description>
			<content:encoded><![CDATA[<style type="text/css">
  #experimenting_with_html_minifier .footnotes { font-size: 0.85em; }
  #experimenting_with_html_minifier ul ul { margin: 0.5em 0 0 0; }
  #experimenting_with_html_minifier ul ul li { margin-bottom: 0.25em; }
  #experimenting_with_html_minifier ul li { margin-bottom: 1em; }
  #experimenting_with_html_minifier h4 { font-size: 1em; }
</style>
<div id="experimenting_with_html_minifier">
<ul id="toc" style="display:none;">
<li>
      <a href="#how_it_works">How it works</a></p>
<ul>
<li>
          <a href="#parser">Parser</a>
        </li>
<li>
          <a href="#minifier">Minifier</a>
        </li>
<li>
          <a href="#test_suite">Test suite</a>
        </li>
<li>
          <a href="#lint">Lint</a>
        </li>
</ul>
</li>
<li>
      <a href="#options">Options</a></p>
<ul>
<li><a href="#remove_comments">Remove comments</a></li>
<li><a href="#remove_comments_from_scripts_and_styles">Remove comments from scripts and styles</a></li>
<li><a href="#remove_cdata_sections">Remove CDATA sections</a></li>
<li><a href="#collapse_whitespace">Collapse whitespace</a></li>
<li><a href="#collapse_boolean_attributes">Collapse boolean attributes</a></li>
<li><a href="#remove_attribute_quotes">Remove attribute quotes</a></li>
<li><a href="#remove_redundant_attributes">Remove redundant attributes</a></li>
<li><a href="#use_short_doctype">Use short doctype</a></li>
<li><a href="#remove_empty_or_blank_attributes">Remove empty (or blank) attributes</a></li>
<li><a href="#remove_optional_tags">Remove optional tags</a></li>
<li><a href="#remove_empty_elements">Remove empty elements</a></li>
<li><a href="#validate_input_through_html_lint">Validate input through HTML lint</a></li>
</ul>
</li>
<li>
      <a href="#field_testing">Field-testing</a>
    </li>
<li>
      <a href="#cost_and_benefits">Cost and benefits</a>
    </li>
<li>
      <a href="#future">Future</a>
    </li>
</ul>
<p>In <a href="http://perfectionkills.com/optimizing-html/">Optimizing HTML</a>, I mentioned that state of HTML minifiers is <a href="http://perfectionkills.com/optimizing-html/#tools">rather crude at the moment</a>. We have a large variety of JS and CSS minification tools, but almost no HTML ones. This is actually <strong>quite understandable</strong>. </p>
<p>First of all, minifiying scripts and stylesheets usually results in better savings, overall. Second, the nature of document markup is much more dynamic than that of scripts and styles. As a result, HTML minification has to be done &#8220;on demand&#8221;, and carries certain overhead. Only when this overhead is less then <strong>difference in time for delivering minified-vs-original document</strong>, there&#8217;s a benefit in minification. In some cases, though, savings in document size (and so bandwidth) can be more important than time spent on minification.</p>
<p>It&#8217;s no suprise that HTML minification is almost always a <strong>low-priority optimization</strong>. When it comes to client-side performance, there are certainly other <a href="http://stevesouders.com/hpws/rules.php">more important things</a> to pay attention to. Only when other aspects are taken into consideration, it is worth minifying document markup.</p>
<p>Few weeks ago, I decided to experiment with <strong>Javascript-based HTML minifier</strong> and created an online-based tool, with lint-like capabilities. After some tweaking, the script was able to parse and minify markup of almost any random website. The goal was to see how easy it is to implement something like this, learn HTML a bit more, and have fun in a process. Ultimately, I wanted to minify some of the popular websites and see if savings are worth all the trouble.</p>
<p>Today, I&#8217;d like to share <a href="http://kangax.github.com/html-minifier/">this tool</a> with you. I&#8217;ll quickly go over some of the initial features, explain how minifier works, and look into possible side effects of minification. Please note that <strong>the script is still in very early stage</strong>, and shouldn&#8217;t be used in production. If you are not interested in inner workings, feel free to skip to <a href="#field_testing">tests</a> or <a href="#cost_and_benefits">conclusions</a>.</p>
<p>
    <a href="http://kangax.github.com/html-minifier/"><br />
      <img src="/images/minifier-screenshot.png" alt="Screenshot of HTMLMinifier"><br />
    </a>
  </p>
<h3 id="how_it_works">How it works</h3>
<h4 id="parser">Parser</h4>
<p>At its core, minifier relies on <a href="http://ejohn.org/blog/pure-javascript-html-parser/">HTML parser by John Resig</a>. John&#8217;s parser was capable of handling quite complex documents, but would sometimes trip on some of the more obscure structures. For example, doctype declarations were not understood at all. Whenever attribute name contained characters like &#8220;-&#8221; (e.g. as in &#8220;http-equiv&#8221;), parser would fail. There were also some defficiencies in regular expressions for matching comments and CDATA sections: newlines inside them were not accounted for, so multiline comments simply weren&#8217;t matched. CDATA sections and comments inside elements with CDATA content model (e.g. SCRIPT and STYLE) were getting stripped for no apparent reason.</p>
<p>All of these are <a href="http://github.com/kangax/html-minifier/blob/gh-pages/src/htmlparser.js">now fixed</a>.</p>
<h4 id="minifier">Minifier</h4>
<p>Minifier is a very small &#8220;wrapper&#8221; on top of parser. As of now it&#8217;s only about 250 LOC. It takes input string and configuration object; passes this input string to parser, and builds final output according to specified options.</p>
<p>For example, we can tell it to <strong>remove comments</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> input <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;!-- foo --&gt;&lt;div&gt;baz&lt;/div&gt;&lt;!-- bar<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span> moo --&gt;'</span><span style="color: #339933;">;</span>
    minify<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> removeComments<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// '&lt;div&gt;baz&lt;/div&gt;'</span></pre></div></div>

<p>or to <strong>collapse boolean attributes</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> input <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;input disabled=&quot;disabled&quot;&gt;'</span><span style="color: #339933;">;</span>
    minify<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> collapseBooleanAttributes<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// '&lt;input disabled&gt;'</span></pre></div></div>

<h4 id="test_suite">Test suite</h4>
<p>One of the goals I had for this little project was to have a robust test suite. <strong>HTML minifier is fully unit tested</strong> with <a href="https://github.com/kangax/html-minifier/blob/gh-pages/tests/index.html">~100 tests at the moment</a>. This has few benefits: anyone can change, tweak or add things without worrying to break existing functionality. It takes literally seconds to tell if script is functional in certain browser (or even in non-browser implementation, such as node.js on a server)—simply by running a test suite. Finally, tests can serve as documentation for how minifier handles some of the edge cases.</p>
<h4 id="lint">Lint</h4>
<p>While working on minifier, I realized that oftentimes the most wasteful part of the markup is not white space, comments or boolean attributes, but inline styles, scripts, presentational or deprecated elements and attributes. None of these can be simply stripped, as that could affect state of the document and is just too obtrusive. What can be done, however, is reporting of these occurences to the user. HTMLLint is even a smaller script, whose job is exactly that—to log any deprecated or presentational elements/attributes encountered during parsing. Additionally, it detects event attributes (e.g. onclick, onmouseover, etc.). The rationale for this is that moving contents of event attributes to external script allows to <a href="http://perfectionkills.com/optimizing-html/#3_onclick_onmouseover_etc">take advantage of resource caching</a>.</p>
<h3 id="options">Options</h3>
<p>Before we begin, it&#8217;s important to understand that <strong>minifier parses documents as HTML, not XHTML</strong>. This allows to employ such optimizations as &#8220;remove optional tags and quotes&#8221;, &#8220;collapse boolean attributes&#8221;, etc. Note that almost none of the options affect document validity, as per HTML 4.01. XHTML support might be added in the future, but considering that in context of pubilc web <a href="http://hixie.ch/advocacy/xhtml">it&#8217;s mostly pointless at the moment</a>, I see little reason in doing so. Besides, minifying XHTML documents (given that they&#8217;re actually served to clients properly, with &#8220;application/xhtml+xml&#8221;) doesn&#8217;t reduce size as much as if they were HTML.</p>
<p>The following is a list of current options in minifier. It is far from being exhaustive, and will most likely be extended in a future. Let&#8217;s look at each one of them quickly:</p>
<h4 id="remove_comments">Remove comments</h4>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> input <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;!-- some comment --&gt;&lt;p&gt;blah&lt;/p&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> output <span style="color: #339933;">=</span> minify<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> removeComments<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    output<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// '&lt;p&gt;blah&lt;/p&gt;'</span></pre></div></div>

<p>This one should be self-explanatory. Passing truthy <code>removeComments</code> tells minifier to strip HTML comments. Note that comments inside elements with CDATA content model, such as SCRIPT and STYLE, are left intact (but see next option).</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    var input = '<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;&lt;!--</span> some comment <span style="color: #339933;">--&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>';
    var output = minify(input, { removeComments: true });
&nbsp;
    output; // '<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;&lt;!--</span> some comment <span style="color: #339933;">--&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>'</pre></div></div>

<h4 id="remove_comments_from_scripts_and_styles">Remove comments from scripts and styles</h4>
<p>When this option is enabled, HTML comments in scripts and styles are stripped as well:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    var input = '<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;&lt;!--</span>\n <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">--&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>';
    var output = minify(input, { removeCommentsFromCDATA: true });
&nbsp;
    output; // '<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>alert<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span>'</pre></div></div>

<p>It&#8217;s worth pointing out that there&#8217;s a slight difference in the way HTML comments are treated inside SCRIPT and STYLE elements. In scripts, comment start delimiter (&#8220;&lt;!-<span></span>-&#8221;) tells parser to ignore everything until newline:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #339933;">&lt;!--</span> <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// alert never happens!</span>
    <span style="color: #339933;">&lt;!--</span>
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// but this one does!</span>
    <span style="color: #006600; font-style: italic;">// &quot;&lt;!--&quot; acts as a single-line JS comment (&quot;//&quot;).</span></pre></div></div>

<p>In styles, however, &#8220;&lt;!-<span></span>-&#8221; is simply ignored when it&#8217;s present in the beginning of input (I haven&#8217;t tested what happens in other parts of a stylesheet). Contrary to script behavior, anything that follows &#8220;&lt;!-<span></span>-&#8221; <strong>still remains present</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">    &lt;!-- body <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">red</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span> --<span style="color: #00AA00;">&gt;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/*  treated as:
        body { color: red; }
    */</span></pre></div></div>

<p><a href="http://perfectionkills.com/optimizing-html/#1_html_comments_in_scripts">Explanation of why you might want to strip comments.</a></p>
<h4 id="remove_cdata_sections">Remove CDATA sections</h4>
<p>This option removes CDATA sections from script and style elements:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> input <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;script&gt;/* &lt;![CDATA[ <span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span> */alert(1)/* ]]&gt; */&lt;/script&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> output <span style="color: #339933;">=</span> minify<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> removeCDATASectionsFromCDATA<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    output<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// '&lt;script&gt;alert(1)&lt;/script&gt;'</span></pre></div></div>

<p><a href="http://perfectionkills.com/optimizing-html/#2_cdata_8230_sections">Explanation of why you might want to do this.</a></p>
<h4 id="collapse_whitespace">Collapse whitespace</h4>
<p>This options collapses white space that contributes to text nodes in a document tree. For example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> input <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;div&gt; &lt;p&gt;    foo &lt;/p&gt;    &lt;/div&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> output <span style="color: #339933;">=</span> minify<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> collapseWhitespace<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    output<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// '&lt;div&gt;&lt;p&gt;foo&lt;/p&gt;&lt;/div&gt;'</span></pre></div></div>

<p>It doesn&#8217;t affect significant white space; e.g. in contents of elements like SCRIPT, STYLE, PRE or TEXTAREA. </p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> input <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;script&gt;    alert(&quot;foo     bar&quot;)&lt;/script&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> output <span style="color: #339933;">=</span> minify<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> collapseWhitespace<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    output<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// '&lt;script&gt;alert(&quot;foo     bar&quot;)&lt;/script&gt;'</span>
&nbsp;
    input <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;textarea&gt;     x x   x &lt;/textarea&gt;'</span><span style="color: #339933;">;</span>
    output <span style="color: #339933;">=</span> minify<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> collapseWhitespace<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    output<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// '&lt;textarea&gt;     x x   x &lt;/textarea&gt;'</span></pre></div></div>

<p>Now, it&#8217;s worth mentioning that <strong>this modification can have side effects</strong>, and significantly change document representation. </p>
<p>For example, markup like <code>&lt;span>foo&lt;/span> &lt;span>bar&lt;/span></code> is usually displayed as &#8220;foo bar&#8221; in browsers, with one space character in between two words. White space in markup is represented as text node in document tree. This text node&#8217;s value is a white space (e.g. <code>U+0020</code>), and as long as two adjacent elements are <a href="http://www.w3.org/TR/CSS2/visuren.html#inline-level">inline-level</a>—as they are in this example—it is this white space that contributes to a gap in between &#8220;foo&#8221; and &#8220;bar&#8221;. As soon as we remove that white space (i.e. changing markup to <code>&lt;span>foo&lt;/span>&lt;span>bar&lt;/span></code>), representation changes from &#8220;foo bar&#8221; to &#8220;foobar&#8221;.</p>
<p>There are two ways to work around this issue.</p>
<p>First one is not to rely on such white space for document representation, and instead style elements to have margins and paddings as needed. In previous example, this could have been: <code>&lt;span class="foo">foo&lt;/span>&lt;span>bar&lt;/span></code> (where foo class would be declared with, say, <code>margin-right: 0.25em;</code>). At first, this might seem like an overkill. After all, adding class seems to defeat the purpose, resulting in larger output, when compared to a version with just one white space character. However, depending on a context, giving few elements a class for styling purposes, and then stripping white space <em>from the entire document</em>, can result in a smaller output.</p>
<p>Second option is to never <em>fully remove</em> white space characters, and instead always <strong>collapse them to one</strong> white space character. HTML 4.01 is actually <a href="http://www.w3.org/TR/html401/struct/text.html#whitespace">specified to do just that</a>, so there&#8217;s no harm in doing it upfront. Because of this, the following 2 snippets should render identically:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">  &lt;span&gt;foo&lt;/span&gt;
&nbsp;
     &lt;span&gt;bar&lt;/span&gt;</pre></div></div>

<p>and:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">    &lt;span&gt;foo&lt;/span&gt; &lt;span&gt;bar&lt;/span&gt;</pre></div></div>

<p>&#8230;with one space in between &#8220;foo&#8221; and &#8220;bar&#8221;. Note how in first case, there&#8217;s an entire sequence of white space characters (including line breaks). </p>
<p>This second option&mdash;collapsing to one white space&mdash;has not yet been added to minifier.</p>
<p><strong>Another noticeable effect</strong> white space removal can have on a document is related to CSS <a href="http://www.w3.org/TR/CSS2/text.html#white-space-prop">white-space property</a>. As I mentioned earlier, by default, adjacent sequences of white space in most of the elements collapse into one space character. But <code>white-space</code> property changes it all. Some of its values result in different collapsing behavior. <code>white-space: pre</code>, for example, makes whitespace render exactly as it occurs in a markup.</p>
<p>As a result, snippet like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;span style=&quot;white-space:pre;&quot;&gt;  foo     bar&lt;/span&gt;</pre></div></div>

<p>  renders exactly as is, and becomes:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">  foo     bar</pre></div></div>

<p>As of now, minifier <strong>doesn&#8217;t respect space-preserving white-space values</strong> (i.e. &#8220;pre&#8221; and &#8220;pre-wrap&#8221;). It doesn&#8217;t even understand them. Unfortunately, computing elements&#8217; styles and determining their white-space values would be just way too complex and impractical <sup><a href="#footnote1">[1]</a></sup>. On a bright side, it seems that white-space property is not used very often. In a future, it should be possible to add an option to minifier for specifying a way to prevent certain elements from having their content collapsed. A filtering can be based on a class, a simple selector, or maybe even by parsing element&#8217;s style attribute.</p>
<h4 id="collapse_boolean_attributes">Collapse boolean attributes</h4>
<p>HTML 4.01 has so-called <a href="http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.3.4.2">boolean attributes</a>—&#8220;selected&#8221;, &#8220;disabled&#8221;, &#8220;checked&#8221;, etc. These may appear in a minimized (collapsed) form, where attribute value is fully ommited. For example, instead of writing <code>&lt;input disabled="disabled"></code>, we can simply write—<code>&lt;input disabled></code>.</p>
<p>Minifier has an option to perform this optimization, called <code>collapseBooleanAttributes</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> input <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;input value=&quot;foo&quot; readonly=&quot;readonly&quot;&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> output <span style="color: #339933;">=</span> minify<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> collapseBooleanAttributes<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    output<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// '&lt;input value=&quot;foo&quot; readonly&gt;'</span></pre></div></div>

<p>A <strong>potential caveat here</strong> is that if you target elements <em>by attribute name and value</em>, things might break after applying this optimization. Granted, this kind of case seems rather unreal, but here&#8217;s an example. If we had these rules:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">    input<span style="color: #00AA00;">&#91;</span>disabled<span style="color: #00AA00;">&#93;</span> <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">red</span> <span style="color: #00AA00;">&#125;</span>
    input<span style="color: #00AA00;">&#91;</span>disabled<span style="color: #00AA00;">=</span><span style="color: #ff0000;">&quot;disabled&quot;</span><span style="color: #00AA00;">&#93;</span> <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">green</span> <span style="color: #00AA00;">&#125;</span>
    input<span style="color: #3333ff;">:disabled </span><span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">blue</span> <span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>and markup like <code>&lt;input disabled="disabled"></code>, then after transforming it to <code>&lt;input disabled></code>, second rule—<code>input[disabled="disabled"]</code>—would stop matching an element. First and third ones, however, would still work as expected. I can&#8217;t imagine why someone would use this second version, and you probably won&#8217;t ever stumble upon issues like these, but it&#8217;s good to be aware of them.</p>
<h4 id="remove_attribute_quotes">Remove attribute quotes</h4>
<p>By default, SGML (which HTML originates from) requires that all attribute values be delimited using either double or single quotes. But in certain cases—when attribute values contain a specific set of characters—<a href="http://www.w3.org/TR/html401/intro/sgmltut.html#h-3.2.2">quotes can be omitted altogether</a>. Note that <strong>HTML specification recommends to always use quotes</strong>. There&#8217;s also an interesting explanation of <a href="http://www.cs.tut.fi/~jkorpela/qattr.html">why always quoting is a good idea</a> by Jukka Korpela (although none of the dangers he&#8217;s talking about apply here). Please, use this optimization with care.</p>
<p>Relevant option is <code>removeAttributeQuotes</code>, and it tells minifier to omit quotes when it is safe to do so:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> input <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;p class=&quot;foo-bar&quot; id=&quot;moo&quot; title=&quot;blah blah&quot;&gt;foo&lt;/p&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> output <span style="color: #339933;">=</span> minify<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> removeAttributeQuotes<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    output<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// '&lt;p class=foo-bar id=moo title=&quot;blah blah&quot;&gt;foo&lt;/p&gt;'</span></pre></div></div>

<h4 id="remove_redundant_attributes">Remove redundant attributes</h4>
<p>Some attributes in HTML 4.01 have default values. For example, input&#8217;s type attribute defaults to &#8220;text&#8221; and form&#8217;s method—to &#8220;get&#8221;. When enabling corresponding option in minifier (<code>removeRedundantAttributes</code>), these default attribute name-value pairs get stripped from the output. </p>
<p>There are also few other redundancies that are taken care of as part of this optimization.</p>
<p>One of them is removing deprecated language attribute on SCRIPT elements. It was <a href="http://perfectionkills.com/optimizing-html/#7_script_language_javascript">among markup smells I mentioned recently</a>. Another one is <a href="http://perfectionkills.com/optimizing-html/#5_a_id_name">coexisting &#8220;name&#8221; and &#8220;id&#8221; attributes on acnhors</a>. And finally, redundant <a href="http://perfectionkills.com/optimizing-html/#4_onclick_javascript">&#8220;javascript&#8221; labels in event handlers</a>.</p>
<h4 id="use_short_doctype">Use short doctype</h4>
<p>This optimization is the only one <strong>affecting document validity</strong>. That is if document is defined to be anything but HTML5 (such as HTML 4.01). When <code>useShortDoctype</code> option is enabled, existing doctype is replaced with its short (HTML5) version—<code>&lt;!DOCTYPE html></code>. As mentioned before, <a href="http://perfectionkills.com/optimizing-html/#6_doctype_html">this replacement is generally pretty safe</a>, but you should decide for yourself if this is something worth doing.</p>
<h4 id="remove_empty_or_blank_attributes">Remove empty (or blank) attributes</h4>
<p>The corresponding option is <code>removeEmptyAttributes</code>, and when enabled, all attributes with empty values are simply removed from the output. This includes blank values as well—those consisting of white space only.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> input <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;p id=&quot;&quot; STYLE=&quot; &quot; title=&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot; &gt;foo&lt;/p&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> ouptut <span style="color: #339933;">=</span> minify<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> removeEmptyAttributes<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    output<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &lt;p&gt;foo&lt;/p&gt;</span></pre></div></div>

<p>Note that not all &#8220;empty&#8221; attributes are removed. For example, both &#8220;src&#8221; and &#8220;alt&#8221; attributes are required on IMG elements, so we can&#8217;t remove them, even if they&#8217;re empty. Right now, only <a href="http://www.w3.org/TR/html4/sgml/dtd.html#coreattrs">core attributes</a> (id, class, style, title), <a href="http://www.w3.org/TR/html4/sgml/dtd.html#i18n">i18n ones</a> (lang, dir) and <a href="http://www.w3.org/TR/html4/sgml/dtd.html#events">event ones</a> (onclick, ondblclick, etc.) are considered &#8220;safe&#8221; for removal.</p>
<p>The caveat here is that, similar to &#8220;collapse boolean attributes&#8221; option, <strong>this change can affect certain style or script behavior</strong>. For example, you might want to target all elements with class attribute—<code>*[class] { ... }</code>. This will apply to elements with empty class, such as <code>&lt;p class="">bar&lt;/p></code>, but obviously not to those without—<code>&lt;p>bar&lt;/p></code>. </p>
<p>This might not be a big issue, but take it into consideration.</p>
<h4 id="remove_optional_tags">Remove optional tags</h4>
<p>Some elements in HTML 4.01 are allowed to have their tags omitted. Optional tags are either <strong>end one</strong> (e.g. <code>&lt;/td></code>) or both—<strong>start and end ones</strong> (e.g. <code>&lt;tbody></code> and <code>&lt;/tbody></code>). Note that start tag can never be optional on its own.</p>
<p>Corresponding option in minifier is <code>removeOptionalTags</code>. Currently, it only strips end tags of HTML, HEAD, BODY, THEAD, TBODY and TFOOT elements. I don&#8217;t fully understand the process of creating document tree from &#8220;unclosed&#8221; markup, so I&#8217;m not sure when it&#8217;s safe to omit tags like <code>&lt;/p></code>.</p>
<p>For example, I can see how removing BODY start tag <strong>can have side effects</strong>. Let&#8217;s say we have a markup like this (with omitted HTML 4.01 doctype, for brevity):</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">    &lt;head&gt;
      &lt;title&gt;x&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
      &lt;p&gt;x&lt;/p&gt;
      &lt;script type=&quot;text/javascript&quot;&gt;
        document.write(document.body.childNodes[0].nodeName);
      &lt;/script&gt;
    &lt;/body&gt;</pre></div></div>

<p>and the same markup with HEAD and BODY tags removed:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">    &lt;title&gt;x&lt;/title&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    &lt;p&gt;x&lt;/p&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
      document.write(document.body.childNodes[0].nodeName);
    &lt;/script&gt;</pre></div></div>

<p>Note that second version is a perfectly valid document. It just has start and end tags of HEAD and BODY elements omitted. Now what seems to happen here, in a second version, is this: </p>
<p>Browser starts parsing, encounters TITLE tag, and given lack of starting HTML and HEAD tags, creates both elements implicitly (first, HTML, then HEAD as its immediate child). It then continues parsing, up until it stumbles upon P element, which, as per <a href="http://www.w3.org/TR/REC-html40/sgml/dtd.html">DTD</a>, can not be a child of HEAD. Browser is therefore forced to implicitly close HEAD element, start BODY element, and continue parsing further. P element becomes first child in BODY, and SCRIPT element becomes last child in HEAD.</p>
<p>Now, if we were to display both of these documents, first one would alert &#8220;SCRIPT&#8221; and second one—&#8220;P&#8221;. This is becase in original version, SCRIPT element is <em>defined explicitly</em> to be a child of BODY, and in modified version—child of HEAD (due to the way parsing works). The behavior of two documents is therefore not identical. We&#8217;ve got a &#8220;problem&#8221;.</p>
<p>Just like with previous &#8220;gotchas&#8221;, I&#8217;m not sure how likely this type of scenario is to appear in real life. From what I can see, the only other element (besides SCRIPT), allowed as child of both—HEAD and BODY, is OBJECT. As for the future, it should be possible to make minifier strip other optional tags as well. But only in safe scenarios.</p>
<p>It&#8217;s also worth mentioning that unclosed elements <a href="http://perfectionkills.com/optimizing-html/#comment-57196">can result in slightly slower parsing times</a>. Unfortunately, there are no extensive benchmarks done on this topic, and results seem to vary across browsers.</p>
<h4 id="remove_empty_elements">Remove empty elements</h4>
<p>This optimization is probably <strong>one of the most obtrusive ones</strong>, which is why it is disabled by default. Think of it as an experimental addition, and employ with great care. There are dozens of valid use cases for occurence of empty elements in a document. They can be used as  placeholders for content inserted later with scripting; or for presentational purposes, such as to implement rounded corners, shadows, float clearing, etc. There are probably other cases, which I can&#8217;t think of at the moment.</p>
<p>When enabled, minifier simply removes all elements with empty contents (but not those with <strong>empty content model</strong>, such as IMG, LINK, or BR). </p>
<p>For example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> input <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;p&gt;&lt;/p&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> output <span style="color: #339933;">=</span> minify<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> removeEmptyElements<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    output<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// ''</span>
&nbsp;
    input <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;div&gt;blah&lt;span&gt;&lt;/span&gt;&lt;/div&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> output <span style="color: #339933;">=</span> minify<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> removeEmptyElements<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    output<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// '&lt;div&gt;blah&lt;/div&gt;';</span></pre></div></div>

<p>There are few things to be aware of. First of all, elements containing <em>only other empty elements</em> are not removed. For example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> input <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> output <span style="color: #339933;">=</span> minify<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> removeEmptyElements<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    output<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// '&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;'</span></pre></div></div>

<p>Note how only inner DIV element—the one with actual empty contents—is removed.</p>
<p>Second of all, only truly empty string is considered an empty content. This does <em>not</em> include spaces, newlines, or other white space characters:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> input <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;p&gt; &lt;/p&gt;'</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// note one space character in between</span>
    <span style="color: #003366; font-weight: bold;">var</span> output <span style="color: #339933;">=</span> minify<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> removeEmptyElements<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    output<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// '&lt;p&gt; &lt;/p&gt;'</span></pre></div></div>

<p>Also note that comments are parsed as separate entities and so don&#8217;t affect &#8220;emptiness&#8221; of elements:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> input <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;p&gt;&lt;!-- comment --&gt;&lt;/p&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> output <span style="color: #339933;">=</span> minify<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> removeEmptyElements<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    output<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// ''</span></pre></div></div>

<p>As with other optimizations, some of these limitations will likely be removed in the future.</p>
<h4 id="validate_input_through_html_lint">Validate input through HTML lint</h4>
<p>This option simply toggles linting. You can create new HTMLLint object and pass it to minifier. During minification, lint object silently logs all &#8220;suspicious&#8221; activity. It exposes <code>populate</code> method, which accepts element and inserts its log into this element:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> lint <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> HTMLLint<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    minify<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">' some input... '</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> lint<span style="color: #339933;">:</span> lint <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    lint.<span style="color: #660066;">populate</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'someElement'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3 id="field_testing">Field-testing</h3>
<p>So how does minifier stand against real-life markup? Let&#8217;s take a look at minification results of some of the popular websites (note that when gzip&#8217;ing documents, <strong>6th level of compression (default)</strong> was used):</p>
<h4 id="amazoncom">Amazon.com</h4>
<p>Original size:  217KB (35.8KB gzipped)<br />
  Minified size:  206.6KB (34.3KB gzipped)<br />
  Savings:        <strong>10.4KB</strong> (1.5KB gzipped)</p>
<p>Minifying home page of <a href="http://amazon.com">amazon.com</a> saves about 10KB with uncompressed document, and only 1.5KB with compressed one. What&#8217;s interesting is that humongous 217KB is actually a result of miriad of inline styles and scripts scattered throughout a document. Replacing those with external scripts would be the best optimization. Getting rid of occasional style attributes would help too.</p>
<h4 id="diggcom">Digg.com</h4>
<p>Original size:   82KB (18.2KB gzipped)<br />
  Minified size:   74.9KB (17.2KB gzipped)<br />
  Savings:         <strong>7KB</strong> (1KB gzipped)</p>
<p>On <a href="http://digg.com">digg.com</a>, reduction is slightly smaller—7KB (1KB gzipped). The markup is not as cluttered as on amazon, but still has smells: inline scripts (and unnecessary comments in them), deprecated attributes, anchors defunct without scripting, etc. The benefits of minification are rather small here.</p>
<h4 id="ajaxiancom">Ajaxian.com</h4>
<p>Original size:  177.6KB (32.4KB gzipped)<br />
  Minified size:  157.3KB (29.7KB gzipped)<br />
  Savings:        <strong>20.3KB</strong> (2.7KB gzipped)</p>
<p>Trying out home page of <a href="http://ajaxian.com">ajaxian.com</a>, we see a difference of ~20KB—even better reduction in size. And again, compressed documents show savings of only 2.7KB. Speaking of compression, ajaxian.com shamelessly serves its 177KB-large document uncompressed. There&#8217;s also some redundant markup, like unnecessary &amp;nbsp;&#8217;s, excessive style attributes, lots of comments, and few inline scripts. Removing all of those, and turning on compression would be an ultimate optimization.</p>
<h4 id="linkedincom">Linkedin.com</h4>
<p>Original size:  128.8KB (19.8KB gzipped)<br />
  Minified size:  89.4KB (17.1KB gzipped)<br />
  Savings:        <strong>39.4KB</strong> (2.7KB gzipped)</p>
<p><a href="http://linkedin.com">linkedin.com</a> surprises with savings of almost 40KB (!) after minification. Looking at the source, we see that large number is explained by excessive amount of whitespace. This is a good example of how carelessly used whitespace can add up to huge number like this. And again, gzip saves the day; minifying compressed document reduces it only by 2.7KB.</p>
<h4 id="ecmascript_language_specification">ECMAScript language specification</h4>
<p>Original size:  703KB (122.5KB gzipped)<br />
  Minified size:  572KB (106.4KB gzipped)<br />
  Savings:        <strong>131KB</strong> (16KB gzipped)</p>
<p>Large static documents is where HTML minification truly shines, and <a href="http://bclary.com/2004/11/07/">HTML version of ECMAScript (3rd ed.) language specification</a> is a clear demonstration of it. Minifying document results in savings of 131KB (!) for an uncompressed document, and 16KB for compressed one. Since document is served statically, there&#8217;s hardly any reason not to apply minification here.</p>
<h3 id="cost_and_benefits">Cost and benefits</h3>
<p>It&#8217;s pretty obvious that the best candidates for html minification are <strong>large static documents</strong>. Or just static documents—FAQ&#8217;s, standalone articles, etc. Anything that can&#8217;t be compressed (e.g. if there are not enough access rights, to enable gzip on a server) would benefit from minification as well. Even when serving gzipped content, it&#8217;s worth remembering that <a href="http://www.stevesouders.com/blog/2009/11/11/whos-not-getting-gzip/">not everyone is getting gzip</a>. So clients that are being sent gzipped content could receive 2-3KB smaller file, whereas those receiving uncompressed content could end up with files up to whopping 10-20KB smaller than original ones.</p>
<p>One of the biggest problems I see, when it comes to dynamic minification, is the <strong>possibility of error</strong>. The core of the issue is that minification relies on parsing, and parsing HTML is <a href="http://www.codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html">a pretty tricky business</a>. Even though minifier applies a strict set of rules—removing quotes and optional tags only when it is absolutely safe to do so, a single misplaced character in start tag can trip parser and wreak havoc on an entire document. This is especially relevant when there&#8217;s an inclusion of user-generated content. </p>
<p>As an example, browsers usually understand <strong>empty end tags</strong> (allowed in HTML)—<code>&lt;p> test &lt;/></code>, but parser, which minifier is based on, would immediately choke here and stop. Another example is attributes containing &#8220;weird&#8221; characters—<code>&lt;a href="http://example.com""> test &lt;/a></code> (note trailing quote after an attribute). Many browsers happily parse this element, ignoring trailing quote. But parser, once again, falls short and bails out.</p>
<p>It&#8217;s certainly possible to tame errors and simply output original, uncompressed document. But this brings us to another downside—<strong>time spent on minification</strong>. Even when errors are not an issue, there&#8217;s an actual overhead of parsing and processing document tree. Minifying home page of amazon.com in pretty speedy nightly webkit, for example, takes exactly 1 second. Most of that time is consumed by parsing. 1 second is quite a lot. An acceptable time for real-time minification would be somewhere around 50-100ms. This problem can be mitigated by optimizing parser, or porting script to be executed in a faster environment (v8 on a server?).</p>
<p>Curiously, Opera 10.50 beta (on Mac OS X) managed to beat WebKit and completed this task almost twice faster (~500ms). Unfortunately, this version suffers from <a href="http://twitter.com/kangax/status/10037801979">some bugs in regex matching</a>, and fails half of the test suite. Hopefully, those issues will be resolved in later revisions.</p>
<p>Another interesting performance observation was with <a href="http://code.google.com/p/v8/">V8 engine</a>. When testing with version 1.3.x, the time it took to minify amazon.com home page was 0.6 secs. However, version 2.1.2.6 (currently latest stabe) performed same task in excruciatingly long 2 seconds.</p>
<h3 id="future">Future</h3>
<p>I can think of many other things to improve in minifier. Unfortunately, I don&#8217;t have much time to work on it. The project is licensed under MIT, and is free for use/modification by anyone interested. Test suite should make collaboration easy. There&#8217;s a short todo list on a bottom of project page. Among other things, it lists some of the known bugs.</p>
<p>As always, any questions, corrections, and suggestions are very much welcomed.</p>
<p>Enjoy.</p>
<p id="footnote1" class="footnotes">
    1. &#8220;white-space: pre&#8221; declaration could be part of a rule from within an extrnal stylesheet; getting computed style would require downloading, parsing and analyzing every single stylesheet linked from the document (or imported from within another stylesheet).
  </p>
</div>
<div class="tweetmeme_button" style="float: right; margin-left: 30px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fperfectionkills.com%2Fexperimenting-with-html-minifier%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fperfectionkills.com%2Fexperimenting-with-html-minifier%2F&amp;source=kangax&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8628792cef804c13af5f8ae4e1ba60e3" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/experimenting-with-html-minifier/feed/</wfw:commentRss>
		<slash:comments>36</slash:comments>
		</item>
		<item>
		<title>Javascript quiz</title>
		<link>http://perfectionkills.com/javascript-quiz/</link>
		<comments>http://perfectionkills.com/javascript-quiz/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 19:14:20 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[ECMA-262]]></category>
		<category><![CDATA[Quiz]]></category>
		<category><![CDATA[[[Delete]]]]></category>
		<category><![CDATA[delete operator]]></category>
		<category><![CDATA[with]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=149</guid>
		<description><![CDATA[

    #javascript-quiz .answers { padding-left: 1em; margin-left: 0 }
    #javascript-quiz .answers li { list-style: none !important; margin-left: 0; }
    #javascript-quiz #quiz-result { background: #efe; padding: 1em; border: 1px solid #afa; }
    #javascript-quiz .notes-about-code { margin-top: 1em; }
    #javascript-quiz .notes-about-code li [...]]]></description>
			<content:encoded><![CDATA[<div id="javascript-quiz">
<style type="text/css">
    #javascript-quiz .answers { padding-left: 1em; margin-left: 0 }
    #javascript-quiz .answers li { list-style: none !important; margin-left: 0; }
    #javascript-quiz #quiz-result { background: #efe; padding: 1em; border: 1px solid #afa; }
    #javascript-quiz .notes-about-code { margin-top: 1em; }
    #javascript-quiz .notes-about-code li { margin-bottom: 0.5em; }
    #javascript-quiz .quiz li { list-style-type: none; }
  </style>
<p>I was recently reminded about <a href="http://dmitry.baranovskiy.com/post/91403200"> Dmitry Baranovsky&#8217;s Javascript test</a>, when N. Zakas answered and <a href="http://www.nczonline.net/blog/2010/01/26/answering-baranovskiys-javascript-quiz/">explained it in a blog post</a>. First time I saw those questions explained was by <a href="http://groups.google.com/group/comp.lang.javascript/msg/ae4d0d92361497f6">Richard Cornford in comp.lang.javascript</a>, although not as thoroughly as by Nicholas.</p>
<p>I decided to come up with my own little quiz. I wanted to keep question not very obscure, practical, yet challenging. They would also cover wider range of topics.</p>
<h3>Host objects</h3>
<p>Contrary to Dmitry&#8217;s test, quiz does <strong>not involve host objects</strong> (e.g. <code>window</code>), as their behavior is unspecified and can vary sporadically across implementations. We are talking about pure ECMAScript (3rd ed.) behavior. Now, it&#8217;s worth pointing out that sometimes implementations <strong>deviate from the standard collectively</strong>, forming their own, de-facto standard. An example of this is <code>for-in</code> statement, where none of the popular implementations throw <code>TypeError</code> when expression evalutes to <code>null</code> or <code>undefined</code> — <code>for (var prop in null) { ... }</code> — and instead just silently ignore it. I tried to avoid these non-standard cases. Every question has a correct answer that can be reproduced in at least one of the major implementations.</p>
<h3>So what are we testing?</h3>
<p>Not a lot really. Quiz mainly focuses on knowledge of scoping, function expressions (and how they differ from function declarations), references, process of variable and function declaration, order of evaluation, and a couple more things like <code>delete</code> operator and object instantiation. These are all relatively simple concepts, which I think every professional Javascript developer should know. Most of these are applied in practice quite often. Ideally, even if you can&#8217;t answer a question, you should be able to infer answer from specs (without executing the snippet). When creating these questions, I made sure I can answer each one of them off the top of my head, to keep things relatively simple.</p>
<p>Note, however, that <strong>not all questions are very practical</strong>, so don&#8217;t worry if you can&#8217;t answer some of them. We don&#8217;t often use <code>with</code> statement, for example, so failing to know/remember its exact behavior is  understandable.</p>
<h3>Few notes about code</h3>
<ul class="notes-about-code">
<li>Assuming ECMAScript 3rd edition (not 5th)</li>
<li>Implementation quirks do not count (assuming standard behavior only)</li>
<li>Every snippet is run as a global code (not as <em>eval</em> or <em>function</em> one)</li>
<li>There are no other variables declared (and host environment is not extended with anything beyond what&#8217;s defined in specs)</li>
<li>Answer should correspond to exact return value of entire expression/statement (or last line)</li>
<li>&#8220;Error&#8221; in answer indicates that overall snippet results in a runtime error</li>
</ul>
<h3>Quiz</h3>
<p>Please make sure you <strong>select answer in each question</strong>, as lack of answer is not checked and counts as failure. The final score is simply a number of wrong answers, less is better. Quiz requires Javascript to be enabled.</p>
<ol class="quiz">
<li>
  1.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> 
      <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">typeof</span> arguments<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<ul class="answers">
<li>
<input type="radio" name="question-1" id="answer-1-1">
          <label for="answer-1-1">&#8220;object&#8221;</label>
        </li>
<li>
<input type="radio" name="question-1" id="answer-1-2">
          <label for="answer-1-2">&#8220;array&#8221;</label>
        </li>
<li>
<input type="radio" name="question-1" id="answer-1-3">
          <label for="answer-1-3">&#8220;arguments&#8221;</label>
        </li>
<li>
<input type="radio" name="question-1" id="answer-1-4">
          <label for="answer-1-4">&#8220;undefined&#8221;</label>
        </li>
</ul>
</li>
<li>
  2.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> f <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> g<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">23</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">typeof</span> g<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<ul class="answers">
<li>
<input type="radio" name="question-2" id="answer-2-1">
          <label for="answer-2-1">&#8220;number&#8221;</label>
        </li>
<li>
<input type="radio" name="question-2" id="answer-2-2">
          <label for="answer-2-2">&#8220;undefined&#8221;</label>
        </li>
<li>
<input type="radio" name="question-2" id="answer-2-3">
          <label for="answer-2-3">&#8220;function&#8221;</label>
        </li>
<li>
<input type="radio" name="question-2" id="answer-2-4">
          <label for="answer-2-4">Error</label>
        </li>
</ul>
</li>
<li>
  3.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>x<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">delete</span> x<span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">return</span> x<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<ul class="answers">
<li>
<input type="radio" name="question-3" id="answer-3-1">
          <label for="answer-3-1">1</label>
        </li>
<li>
<input type="radio" name="question-3" id="answer-3-2">
          <label for="answer-3-2">null</label>
        </li>
<li>
<input type="radio" name="question-3" id="answer-3-3">
          <label for="answer-3-3">undefined</label>
        </li>
<li>
<input type="radio" name="question-3" id="answer-3-4">
          <label for="answer-3-4">Error</label>
        </li>
</ul>
</li>
<li>
  4.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> y <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> x <span style="color: #339933;">=</span> y <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">typeof</span> x<span style="color: #339933;">;</span>
    x<span style="color: #339933;">;</span></pre></div></div>

<ul class="answers">
<li>
<input type="radio" name="question-4" id="answer-4-1">
          <label for="answer-4-1">1</label>
        </li>
<li>
<input type="radio" name="question-4" id="answer-4-2">
          <label for="answer-4-2">&#8220;number&#8221;</label>
        </li>
<li>
<input type="radio" name="question-4" id="answer-4-3">
          <label for="answer-4-3">undefined</label>
        </li>
<li>
<input type="radio" name="question-4" id="answer-4-4">
          <label for="answer-4-4">&#8220;undefined&#8221;</label>
        </li>
</ul>
</li>
<li>
  5.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> f<span style="color: #009900;">&#40;</span>f<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> 
      <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">typeof</span> f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<ul class="answers">
<li>
<input type="radio" name="question-5" id="answer-5-1">
          <label for="answer-5-1">&#8220;number&#8221;</label>
        </li>
<li>
<input type="radio" name="question-5" id="answer-5-2">
          <label for="answer-5-2">&#8220;undefined&#8221;</label>
        </li>
<li>
<input type="radio" name="question-5" id="answer-5-3">
          <label for="answer-5-3">&#8220;function&#8221;</label>
        </li>
<li>
<input type="radio" name="question-5" id="answer-5-4">
          <label for="answer-5-4">Error</label>
        </li>
</ul>
</li>
<li>
  6.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> foo <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> 
      bar<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">baz</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> 
      baz<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> 
      <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">typeof</span> arguments<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>foo.<span style="color: #660066;">bar</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<ul class="answers">
<li>
<input type="radio" name="question-6" id="answer-6-1">
          <label for="answer-6-1">&#8220;undefined&#8221;</label>
        </li>
<li>
<input type="radio" name="question-6" id="answer-6-2">
          <label for="answer-6-2">&#8220;object&#8221;</label>
        </li>
<li>
<input type="radio" name="question-6" id="answer-6-3">
          <label for="answer-6-3">&#8220;number&#8221;</label>
        </li>
<li>
<input type="radio" name="question-6" id="answer-6-4">
          <label for="answer-6-4">&#8220;function&#8221;</label>
        </li>
</ul>
</li>
<li>
  7.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> foo <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
      bar<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">baz</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      baz<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">typeof</span> <span style="color: #009900;">&#40;</span>f <span style="color: #339933;">=</span> foo.<span style="color: #660066;">bar</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<ul class="answers">
<li>
<input type="radio" name="question-7" id="answer-7-1">
          <label for="answer-7-1">&#8220;undefined&#8221;</label>
        </li>
<li>
<input type="radio" name="question-7" id="answer-7-2">
          <label for="answer-7-2">&#8220;object&#8221;</label>
        </li>
<li>
<input type="radio" name="question-7" id="answer-7-3">
          <label for="answer-7-3">&#8220;number&#8221;</label>
        </li>
<li>
<input type="radio" name="question-7" id="answer-7-4">
          <label for="answer-7-4">&#8220;function&#8221;</label>
        </li>
</ul>
</li>
<li>
  8.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> f <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">&quot;1&quot;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span> g<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">typeof</span> f<span style="color: #339933;">;</span></pre></div></div>

<ul class="answers">
<li>
<input type="radio" name="question-8" id="answer-8-1">
          <label for="answer-8-1">&#8220;string&#8221;</label>
        </li>
<li>
<input type="radio" name="question-8" id="answer-8-2">
          <label for="answer-8-2">&#8220;number&#8221;</label>
        </li>
<li>
<input type="radio" name="question-8" id="answer-8-3">
          <label for="answer-8-3">&#8220;function&#8221;</label>
        </li>
<li>
<input type="radio" name="question-8" id="answer-8-4">
          <label for="answer-8-4">&#8220;undefined&#8221;</label>
        </li>
</ul>
</li>
<li>
  9.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      x <span style="color: #339933;">+=</span> <span style="color: #000066; font-weight: bold;">typeof</span> f<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    x<span style="color: #339933;">;</span></pre></div></div>

<ul class="answers">
<li>
<input type="radio" name="question-9" id="answer-9-1">
          <label for="answer-9-1">1</label>
        </li>
<li>
<input type="radio" name="question-9" id="answer-9-2">
          <label for="answer-9-2">&#8220;1function&#8221;</label>
        </li>
<li>
<input type="radio" name="question-9" id="answer-9-3">
          <label for="answer-9-3">&#8220;1undefined&#8221;</label>
        </li>
<li>
<input type="radio" name="question-9" id="answer-9-4">
          <label for="answer-9-4">NaN</label>
        </li>
</ul>
</li>
<li>
  10.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #000066; font-weight: bold;">typeof</span> x<span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">typeof</span> y<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">typeof</span> <span style="color: #000066; font-weight: bold;">typeof</span> x<span style="color: #339933;">;</span></pre></div></div>

<ul class="answers">
<li>
<input type="radio" name="quiz-10" id="answer-10-1">
          <label for="answer-10-1">&#8220;number&#8221;</label>
        </li>
<li>
<input type="radio" name="quiz-10" id="answer-10-2">
          <label for="answer-10-2">&#8220;string&#8221;</label>
        </li>
<li>
<input type="radio" name="quiz-10" id="answer-10-3">
          <label for="answer-10-3">&#8220;undefined&#8221;</label>
        </li>
<li>
<input type="radio" name="quiz-10" id="answer-10-4">
          <label for="answer-10-4">&#8220;object&#8221;</label>
        </li>
</ul>
</li>
<li>
  11.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>foo<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">typeof</span> foo.<span style="color: #660066;">bar</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> foo<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> bar<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span> <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<ul class="answers">
<li>
<input type="radio" name="quiz-11" id="answer-11-1">
          <label for="answer-11-1">&#8220;undefined&#8221;</label>
        </li>
<li>
<input type="radio" name="quiz-11" id="answer-11-2">
          <label for="answer-11-2">&#8220;object&#8221;</label>
        </li>
<li>
<input type="radio" name="quiz-11" id="answer-11-3">
          <label for="answer-11-3">&#8220;number&#8221;</label>
        </li>
<li>
<input type="radio" name="quiz-11" id="answer-11-4">
          <label for="answer-11-4">Error</label>
        </li>
</ul>
</li>
<li>
  12.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      <span style="color: #003366; font-weight: bold;">function</span> f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
      <span style="color: #000066; font-weight: bold;">return</span> f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #003366; font-weight: bold;">function</span> f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<ul class="answers">
<li>
<input type="radio" name="answer-12" id="answer-12-1">
          <label for="answer-12-1">1</label>
        </li>
<li>
<input type="radio" name="answer-12" id="answer-12-2">
          <label for="answer-12-2">2</label>
        </li>
<li>
<input type="radio" name="answer-12" id="answer-12-3">
          <label for="answer-12-3">Error (e.g. &#8220;Too much recursion&#8221;)</label>
        </li>
<li>
<input type="radio" name="answer-12" id="answer-12-4">
          <label for="answer-12-4">undefined</label>
        </li>
</ul>
</li>
<li>
  13.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">function</span> f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> f<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
    <span style="color: #003366; font-weight: bold;">new</span> f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">instanceof</span> f<span style="color: #339933;">;</span></pre></div></div>

<ul class="answers">
<li>
<input type="radio" name="answer-13" id="answer-13-2">
          <label for="answer-13-2">true</label>
        </li>
<li>
<input type="radio" name="answer-13" id="answer-13-1">
          <label for="answer-13-1">false</label>
        </li>
</ul>
</li>
<li>
  14.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #000066; font-weight: bold;">with</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>x<span style="color: #339933;">,</span> undefined<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> length<span style="color: #339933;">;</span></pre></div></div>

<ul class="answers">
<li>
<input type="radio" name="answer-14" id="answer-14-1">
          <label for="answer-14-1">1</label>
        </li>
<li>
<input type="radio" name="answer-14" id="answer-14-2">
          <label for="answer-14-2">2</label>
        </li>
<li>
<input type="radio" name="answer-14" id="answer-14-3">
          <label for="answer-14-3">undefined</label>
        </li>
<li>
<input type="radio" name="answer-14" id="answer-14-4">
          <label for="answer-14-4">Error</label>
        </li>
</ul>
</li>
</ol>
<p id="quiz-result">
<p>  <button type="button" id="submitter">Let&#8217;s see the score!</button></p>
<p>I hope you liked it. Please leave your score in the comments. I&#8217;ll try to explain these questions sometime in a near future, unless someone else does it before me. Meanwhile, you can take a look at my articles on <a href="http://yura.thinkweb2.com/named-function-expressions/">function expressions</a> and <a href="http://perfectionkills.com/understanding-delete/">delete operator</a>, understanding which would help you answer some of these questions, and more importantly, explain their answers.</p>
<p>  <script type="text/javascript" src="/js/quiz.js"></script>
</div>
<div class="tweetmeme_button" style="float: right; margin-left: 30px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fperfectionkills.com%2Fjavascript-quiz%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fperfectionkills.com%2Fjavascript-quiz%2F&amp;source=kangax&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8628792cef804c13af5f8ae4e1ba60e3" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/javascript-quiz/feed/</wfw:commentRss>
		<slash:comments>152</slash:comments>
		</item>
		<item>
		<title>Understanding delete</title>
		<link>http://perfectionkills.com/understanding-delete/</link>
		<comments>http://perfectionkills.com/understanding-delete/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 06:04:18 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[DontDelete]]></category>
		<category><![CDATA[ECMA-262]]></category>
		<category><![CDATA[[[Delete]]]]></category>
		<category><![CDATA[delete operator]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[strict-mode]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=87</guid>
		<description><![CDATA[

    .understanding-delete ul li { margin-bottom: 0; margin-left: 0.75em; }
    .understanding-delete .toc li { margin-bottom: 0.25em; }
    .understanding-delete .toc { margin-left: 0.5em; margin-bottom: 2em; }
    .understanding-delete .toc li ul { margin-bottom: 0.75em; margin-left: 0.5em; margin-top: 0.25em; }
    .understanding-delete .toc ul [...]]]></description>
			<content:encoded><![CDATA[<div class="understanding-delete">
<style type="text/css">
    .understanding-delete ul li { margin-bottom: 0; margin-left: 0.75em; }
    .understanding-delete .toc li { margin-bottom: 0.25em; }
    .understanding-delete .toc { margin-left: 0.5em; margin-bottom: 2em; }
    .understanding-delete .toc li ul { margin-bottom: 0.75em; margin-left: 0.5em; margin-top: 0.25em; }
    .understanding-delete .toc ul li { list-style: lower-alpha outside none; }
    .understanding-delete h4 { font-size: 1em; }
  </style>
<ol class="toc">
<li>
      <a href="#theory" title="">Theory</a></p>
<ul>
<li><a href="#type_of_code" title="">Type of code</a></li>
<li><a href="#execution_context" title="">Execution context</a></li>
<li><a href="#activation_object_variable_object" title="">Activation object / Variable object</a></li>
<li><a href="#property_attributes" title="">Property attributes</a></li>
<li><a href="#built_ins_and_dontdelete" title="">Built-ins and DontDelete</a></li>
<li><a href="#undeclared_assignments" title="">Undeclared assignments</a></li>
</ul>
</li>
<li>
      <a href="#firebug_confusion" title="">Firebug confusion</a></p>
<ul>
<li><a href="#deleting_variables_via_eval" title="">Deleting variables via eval</a></li>
</ul>
</li>
<li>
      <a href="#browsers_compliance" title="">Browsers compliance</a></p>
<ul>
<li><a href="#gecko_dontdelete_bug" title="">Gecko DontDelete bug</a></li>
</ul>
</li>
<li><a href="#ie_bugs" title="">IE bugs</a></li>
<li><a href="#misconceptions" title="">Misconceptions</a></li>
<li><a href="#delete_and_host_objects">`delete` and host objects</a></li>
<li><a href="#es5_strict_mode" title="">ES5 strict mode</a></li>
<li><a href="#summary" title="">Summary</a></li>
</ol>
<p>A couple of weeks ago, I had a chance to glance through Stoyan Stefanov&#8217;s <a href="http://www.amazon.com/Object-Oriented-JavaScript-high-quality-applications-libraries/dp/1847194141">Object-Oriented Javascript</a>. The book had an exceptionally high rating on Amazon (12 reviews with 5 stars), so I was curious to see if it was something worth recommending. I started reading through chapter on functions, and really enjoyed the way things were explained there; the flow of examples was structured in such nice, progressive way, it seemed even beginners would grasp it easily. However, almost immediately I stumbled upon an <strong>interesting misconception</strong> present throughout the entire chapter — deleting functions. There were some other mistakes (such as the difference between function declarations and function expressions), but we aren&#8217;t going to talk about them now.</p>
<p>The book claims that <cite>&#8220;function is treated as a normal variable—it can be copied to a different variable and even deleted.&#8221;</cite>. Following that explanation, there is this example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #339933;">&gt;&gt;&gt;</span> <span style="color: #003366; font-weight: bold;">var</span> sum <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> b<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #000066; font-weight: bold;">return</span> a <span style="color: #339933;">+</span> b<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span> 
  <span style="color: #339933;">&gt;&gt;&gt;</span> <span style="color: #003366; font-weight: bold;">var</span> add <span style="color: #339933;">=</span> sum<span style="color: #339933;">;</span> 
  <span style="color: #339933;">&gt;&gt;&gt;</span> <span style="color: #000066; font-weight: bold;">delete</span> sum
  <span style="color: #003366; font-weight: bold;">true</span>
  <span style="color: #339933;">&gt;&gt;&gt;</span> <span style="color: #000066; font-weight: bold;">typeof</span> sum<span style="color: #339933;">;</span>
  <span style="color: #3366CC;">&quot;undefined&quot;</span></pre></div></div>

<p>Ignoring a couple of missing semicolons, can you see what&#8217;s wrong with this snippet? The problem, of course, is that deleting <code>sum</code> variable should not be successful; <code>delete</code> statement should not evaluate to <code>true</code> and <code>typeof sum</code> should not result in &#8220;undefined&#8221;. All because <strong>it&#8217;s not possible to delete variables</strong> in Javascript. At least not when declared in such way.</p>
<p>So what&#8217;s going on in this example? Is it a typo? A diversion? Probably not. This whole snippet is actually a real output from the <a href="http://getfirebug.com/">Firebug</a> console, which Stoyan must have been using for quick testing. It&#8217;s almost as if Firebug follows some other rules of deletion. It is Firebug that has led Stoyan astray! So what is <strong>really</strong> going on here?</p>
<p>To answer this question, we need to understand how <code>delete</code> operator works in Javascript: what exactly can and cannot be deleted and why. Today I&#8217;ll try to explain this in details. We&#8217;ll take a look at Firebug&#8217;s &#8220;weird&#8221; behavior and realize that it&#8217;s not all that weird; we&#8217;ll delve into what&#8217;s going on behind the scenes when declaring variables, functions, assigning properties and deleting them; we&#8217;ll look at browsers&#8217; compliance and some of the most notorious bugs; we&#8217;ll also talk about strict mode of 5th edition of ECMAScript, and how it changes <code>delete</code> operator behavior.</p>
<p style="background-color:#ffd;padding:0.25em;border:1px solid #fcc;">I&#8217;ll be using Javascript and ECMAScript interchangeable to really mean ECMAScript (unless explicitly talking about Mozilla&#8217;s JavaScript&trade; implementation).</p>
<p>Unsurprisingly, explanations of <code>delete</code> on the web are rather scarce. <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/delete_Operator">MDC article</a> is probably the most comprehensive resource, but unfortunately misses few interesting details about the subject; Curiously, one of these forgotten things is the cause of Firebug&#8217;s tricky behavior. <a href="http://msdn.microsoft.com/en-us/library/2b2z052x%28VS.85%29.aspx">MSDN reference</a> is practically useless.</p>
<h3 id="theory">Theory</h3>
<p>So why is it that we can delete object properties: </p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">var</span> o <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> x<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span> 
  <span style="color: #000066; font-weight: bold;">delete</span> o.<span style="color: #660066;">x</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
  o.<span style="color: #660066;">x</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// undefined</span></pre></div></div>

<p>but not variables, declared like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> 
  <span style="color: #000066; font-weight: bold;">delete</span> x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
  x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 1</span></pre></div></div>

<p>or functions, declared like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">function</span> x<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
  <span style="color: #000066; font-weight: bold;">delete</span> x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;function&quot;</span></pre></div></div>

<p>Note that <code>delete</code> only returns <code>false</code> when a <strong>property can not be deleted</strong>.</p>
<p>To understand this, we need to first grasp such concepts as variable instantiation and property attributes — something that&#8217;s unfortunately rarely covered in books on Javascript. I&#8217;ll try go over these very concisely in the next few paragraphs. It&#8217;s not hard to understand them at all! If you don&#8217;t care about <strong>why things work the way they work</strong>, feel free to skip this chapter.</p>
<h4 id="type_of_code">Type of code</h4>
<p>There are 3 types of executable code in ECMAScript: <strong>Global code</strong>, <strong>Function code</strong> and <strong>Eval code</strong>. These types are somewhat self-descriptive, but here&#8217;s a short overview:</p>
<ol>
<li>When a source text is treated as a Program, it is executed in a global scope, and is considered a <strong>Global code</strong>. In a browser environment, content of SCRIPT elements is usually parsed as a Program, and is therefore evaluated as a Global code.</li>
<li>Anything that&#8217;s executed directly within a function is, quite obviously, considered a <strong>Function code</strong>. In browsers, content of event attributes (e.g. <code>&lt;p onclick="..."&gt;</code>) is usually parsed and treated as a Function code.</li>
<li>Finally, text that&#8217;s supplied to a built-in <code>eval</code> function is parsed as <strong>Eval code</strong>. We will soon see why this type is special.</li>
</ol>
<h4 id="execution_context">Execution context</h4>
<p>When ECMAScript code executes, it always happens within certain <strong>execution context</strong>. Execution context is a somewhat abstract entity, which helps understand how scope and variable instantiation works. For each of three types of executable code, there&#8217;s an execution context. When a function is executed, it is said that control enters <strong>execution context for Function code</strong>; when Global code executes, control enters <strong>execution context for Global code</strong>, and so on. </p>
<p>As you can see, execution contexts can logically form a stack. First there might be Global code with its own execution context; that code might call a function, with its own execution context; that function could call another function, and so on and so forth. Even if function is calling itself recursively, a new execition context is being entered with every invocation.</p>
<h4 id="activation_object_variable_object">Activation object / Variable object</h4>
<p>Every execution context has a so-called <strong>Variable Object</strong> associated with it. Similarly to execution context, Variable object is an abstract entity, a mechanism to describe variable instantiation. Now, the interesing part is that variables and functions declared in a source text are actually <strong>added as properties of this Variable object</strong>. </p>
<p>When control enters execution context for Global code, a Global object is used as a Variable object. This is precisely why variables or functions declared globally <strong>become properties of a Global object</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #009966; font-style: italic;">/* remember that `this` refers to global object when in global scope */</span>
  <span style="color: #003366; font-weight: bold;">var</span> GLOBAL_OBJECT <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> foo <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
  GLOBAL_OBJECT.<span style="color: #660066;">foo</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 1</span>
  foo <span style="color: #339933;">===</span> GLOBAL_OBJECT.<span style="color: #660066;">foo</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">function</span> bar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> GLOBAL_OBJECT.<span style="color: #660066;">bar</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;function&quot;</span>
  GLOBAL_OBJECT.<span style="color: #660066;">bar</span> <span style="color: #339933;">===</span> bar<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span></pre></div></div>

<p>Ok, so global variables become properties of Global object, but what happens with local variables — those declared in Function code? The behavior is actually very similar: they become properties of Variable object. The only difference is that when in Function code, a Variable object is not a Global object, but a so-called <strong>Activation object</strong>. Activation object is created every time execution context for Function code is entered. </p>
<p>Not only do variables and functions declared within Function code become properties of Activation object; this also happens with each of function arguments (under names corresponding to formal parameters) and a special <code>Arguments</code> object (under <code>arguments</code> name). Note that Activation object is an internal mechanism and is never really accessible by program code.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>foo<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> bar <span style="color: #339933;">=</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">function</span> baz<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">/*
    In abstract terms,
&nbsp;
    Special `arguments` object becomes a property of containing function's Activation object: 
      ACTIVATION_OBJECT.arguments; // Arguments object
&nbsp;
    ...as well as argument `foo`:
      ACTIVATION_OBJECT.foo; // 1
&nbsp;
    ...as well as variable `bar`:
      ACTIVATION_OBJECT.bar; // 2
&nbsp;
    ...as well as function declared locally:
      typeof ACTIVATION_OBJECT.baz; // &quot;function&quot;
    */</span>
&nbsp;
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Finally, variables declared within Eval code are <strong>created as properties of calling context&#8217;s Variable object</strong>. Eval code simply uses Variable object of the execution context that it&#8217;s being called within:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">var</span> GLOBAL_OBJECT <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">/* `foo` is created as a property of calling context Variable object,
      which in this case is a Global object */</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'var foo = 1;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  GLOBAL_OBJECT.<span style="color: #660066;">foo</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 1</span>
&nbsp;
  <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">/* `bar` is created as a property of calling context Variable object,
      which in this case is an Activation object of containing function */</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'var bar = 1;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">/* 
      In abstract terms, 
      ACTIVATION_OBJECT.bar; // 1
    */</span>
&nbsp;
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h4 id="property_attributes">Property attributes</h4>
<p>We are almost there. Now that it&#8217;s clear what happens with variables (they become properties), the only remaining concept to understand is property attributes. Every property can have zero or more attributes from the following set — <strong>ReadOnly</strong>, <strong>DontEnum</strong>, <strong>DontDelete</strong> and <strong>Internal</strong>. You can think of them <strong>as flags</strong> — an attribute can either exist on a property or not. For the purposes of today&#8217;s discussion, we are only interested in DontDelete.</p>
<p>When declared variables and functions become properties of a Variable object — either Activation object (for Function code), or Global object (for Global code), these properties are <strong>created with DontDelete attribute</strong>. However, any explicit (or implicit) property assignment creates property <strong>without DontDelete attribute</strong>. And this is essentialy why we can delete some properties, but not others:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">var</span> GLOBAL_OBJECT <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">/*  `foo` is a property of a Global object.
      It is created via variable declaration and so has DontDelete attribute.
      This is why it can not be deleted. */</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> foo <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">delete</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;number&quot;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">/*  `bar` is a property of a Global object.
      It is created via function declaration and so has DontDelete attribute.
      This is why it can not be deleted either. */</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">function</span> bar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
  <span style="color: #000066; font-weight: bold;">delete</span> bar<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> bar<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;function&quot;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">/*  `baz` is also a property of a Global object.
      However, it is created via property assignment and so has no DontDelete attribute.
      This is why it can be deleted. */</span>
&nbsp;
  GLOBAL_OBJECT.<span style="color: #660066;">baz</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'blah'</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">delete</span> GLOBAL_OBJECT.<span style="color: #660066;">baz</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> GLOBAL_OBJECT.<span style="color: #660066;">baz</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;undefined&quot;</span></pre></div></div>

<h4 id="built_ins_and_dontdelete">Built-ins and DontDelete</h4>
<p>So this is what it&#8217;s all about: a special attribute on a property that controls whether this property can be deleted or not. Note that some of the properties of built-in objects are specified to have DontDelete, and so can not be deleted. Special <code>arguments</code> variable (or, as we know now, a property of Activation object) has DontDelete. <code>length</code> property of any function instance has DontDelete as well:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #009966; font-style: italic;">/* can't delete `arguments`, since it has DontDelete */</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">delete</span> arguments<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
    <span style="color: #000066; font-weight: bold;">typeof</span> arguments<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;object&quot;</span>
&nbsp;
    <span style="color: #009966; font-style: italic;">/* can't delete function's `length`; it also has DontDelete */</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">function</span> f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">delete</span> f.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
    <span style="color: #000066; font-weight: bold;">typeof</span> f.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;number&quot;</span>
&nbsp;
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Properties corresponding to function arguments are created with DontDelete as well, and so can not be deleted either:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>foo<span style="color: #339933;">,</span> bar<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">delete</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
    foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 1</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">delete</span> bar<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
    bar<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 'blah'</span>
&nbsp;
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'blah'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h4 id="undeclared_assignments">Undeclared assignments</h4>
<p>As <a href="http://perfectionkills.com/onloadfunction-considered-harmful/#how_does_it_work">you might remember</a>, undeclared assignment <strong>creates a property on a global object</strong>. That is unless that property is found somewhere in the scope chain before global object. And now that we know the difference between property assignment and variable declaration — latter one sets DontDelete, whereas former one doesn&#8217;t — it should be clear why <strong>undeclared assignment creates a deletable property</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">var</span> GLOBAL_OBJECT <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #009966; font-style: italic;">/* create global property via variable declaration; property has DontDelete */</span>
  <span style="color: #003366; font-weight: bold;">var</span> foo <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #009966; font-style: italic;">/* create global property via undeclared assignment; property has no DontDelete */</span>
  bar <span style="color: #339933;">=</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">delete</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;number&quot;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">delete</span> bar<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> bar<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;undefined&quot;</span></pre></div></div>

<p>Note that it is <strong>during property creation</strong> that attributes are determined (i.e. none are set). Later assignments don&#8217;t modify attributes of existing property. It&#8217;s important to understand this distinction.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #009966; font-style: italic;">/* `foo` is created as a property with DontDelete */</span>
  <span style="color: #003366; font-weight: bold;">function</span> foo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009966; font-style: italic;">/* Later assignments do not modify attributes. DontDelete is still there! */</span>
  foo <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">delete</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;number&quot;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">/* But assigning to a property that doesn't exist, 
     creates that property with empty attributes (and so without DontDelete) */</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">bar</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">delete</span> bar<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> bar<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;undefined&quot;</span></pre></div></div>

<h3 id="firebug_confusion">Firebug confusion</h3>
<p>So what happens in Firebug? Why is it that variables declared in console can be deleted, contrary to what we have just learned? Well, as I said before, Eval code has a special behavior when it comes to variable declaration. Variables declared within Eval code are actually <strong>created as properties without DontDelete</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'var foo = 1;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 1</span>
  <span style="color: #000066; font-weight: bold;">delete</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;undefined&quot;</span></pre></div></div>

<p>and, similarly, when called within Function code:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'var foo = 1;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 1</span>
    <span style="color: #000066; font-weight: bold;">delete</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
    <span style="color: #000066; font-weight: bold;">typeof</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;undefined&quot;</span>
&nbsp;
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>And this is the gist of Firebug&#8217;s abnormal behavior. All the text in console seems to be parsed and <strong>executed as Eval code</strong>, not as a Global or Function one. Obviously, any declared variables end up as <strong>properties without DontDelete</strong>, and so can be easily deleted. Be aware of these differences between regular Global code and Firebug console.</p>
<h4 id="deleting_variables_via_eval">Deleting variables via eval</h4>
<p>This interesting <code>eval</code> behavior, coupled with another aspect of ECMAScript can technically allow us to delete non-deletable properties. The thing about function declarations is that they can overwrite same-named variables in the same execution context:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">function</span> x<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
  <span style="color: #003366; font-weight: bold;">var</span> x<span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;function&quot;</span></pre></div></div>

<p>Note how function declaration takes precedence and overwrites same-named variable (or, in other words, same property of Variable object). This is because <strong>function declarations are instantiated after variable declarations</strong>, and are allowed to overwrite them. Not only does function declaration replaces previous value of a property, it <strong>also replaces that property attributes</strong>. If we declare function via <code>eval</code>, that function should also replace that property&#8217;s attributes with its own. And since variables declared from within <code>eval</code> create properties without DontDelete, instantiating this new function should essentially <strong>remove existing DontDelete attribute</strong> from the property in question, making that property deletable (and of course changing its value to reference newly created function).</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #009966; font-style: italic;">/* Can't delete, `x` has DontDelete */</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">delete</span> x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;number&quot;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'function x(){}'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #009966; font-style: italic;">/* `x` property now references function, and should have no DontDelete */</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">typeof</span> x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;function&quot;</span>
  <span style="color: #000066; font-weight: bold;">delete</span> x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// should be `true`</span>
  <span style="color: #000066; font-weight: bold;">typeof</span> x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// should be &quot;undefined&quot;</span></pre></div></div>

<p>Unfortunately, this kind of spoofing doesn&#8217;t work in any implementation I tried. I might be missing something here, or this behavior might simply be too obscure for implementors to pay attention to.</p>
<h3 id="browsers_compliance">Browsers compliance</h3>
<p>Knowing how things work in theory is useful, but practical implications are paramount. Do browsers follow standards when it comes to variable/property creation/deletion? For the most part, yes.</p>
<p>I wrote <a href="http://kangax.github.com/jstests/delete_compliance_test/">a simple test suite</a> to check compliance of <code>delete</code> operator with Global code, Function code and Eval code. Test suite checks both — return value of <code>delete</code> operator, and whether properties are deleted (or not) as they are supposed to. <code>delete</code> return value is not as important as its actual results. It&#8217;s not very crucial if <code>delete</code> returns <code>true</code> instead of <code>false</code>, but it&#8217;s important that properties with DontDelete are not deleted and vice versa.</p>
<p>Modern browsers are generally pretty compliant. Besides this <a href="#deleting_variables_via_eval"><code>eval</code> peculiarity I mentioned earlier</a>, the following browsers pass test suite fully: Opera 7.54+, Firefox 1.0+, Safari 3.1.2+, Chrome 4+.</p>
<p>Safari 2.x and 3.0.4 have problems with deleting function arguments; those properties seem to be created without  DontDelete, so it is possible to delete them. Safari 2.x has even more problems — deleting non-reference (e.g. <code>delete 1</code>) throws error; function declarations create deletable properties (but, strangely, not variable declarations); variable declarations in <code>eval</code> become non-deletable (but not function declarations).</p>
<p>Similar to Safari, Konqueror (3.5, but not 4.3) throws error when deleting non-reference (e.g. <code>delete 1</code>) and erroneously makes function arguments deletable.</p>
<h4 id="gecko_dontdelete_bug">Gecko DontDelete bug</h4>
<p>
    Gecko 1.8.x browsers — Firefox 2.x, Camino 1.x, Seamonkey 1.x, etc. — exhibit an interesting bug where explicitly assigning to a property can remove its DontDelete attribite, even if that property was created via variable or function declaration:
  </p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">function</span> foo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">delete</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false (as expected)</span>
    <span style="color: #000066; font-weight: bold;">typeof</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;function&quot; (as expected)</span>
&nbsp;
    <span style="color: #009966; font-style: italic;">/* now assign to a property explicitly */</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">foo</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// erroneously clears DontDelete attribute</span>
    <span style="color: #000066; font-weight: bold;">delete</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
    <span style="color: #000066; font-weight: bold;">typeof</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;undefined&quot;</span>
&nbsp;
    <span style="color: #009966; font-style: italic;">/* note that this doesn't happen when assigning property implicitly */</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">function</span> bar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
    bar <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">delete</span> bar<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
    <span style="color: #000066; font-weight: bold;">typeof</span> bar<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;number&quot; (although assignment replaced property)</span></pre></div></div>

<p>Surprisingly, Internet Explorer 5.5 &#8211; 8 passes test suite fully except that deleting non-reference (e.g. <code>delete 1</code>) throws error (just like in older Safari). But there are actually <strong>more serious bugs in IE</strong>, that are not immediately apparent. These bugs are related to Global object.</p>
<h3 id="ie_bugs">IE bugs</h3>
<p>The entire chapter just for bugs in Internet Explorer? How unexpected!</p>
<p>In IE (at least, 6-8), the following expression throws error (when evaluated in Global code):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">x</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">delete</span> x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// TypeError: Object doesn't support this action</span></pre></div></div>

<p>and this one as well, but different exception, just to make things interesting:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">delete</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">x</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// TypeError: Cannot delete 'this.x'</span></pre></div></div>

<p>It&#8217;s as if <strong>variable declarations in Global code do not create properties on Global object</strong> in IE. Creating property via assignment (<code>this.x = 1</code>) and then deleting it via <code>delete x</code> throws error. Creating property via declaration (<code>var x = 1</code>) and then deleting it via <code>delete this.x</code> throws another error.</p>
<p>But that&#8217;s not all. Creating property via explicit assignment actually <strong>always throws error on deletion</strong>. Not only is there an error, but created property appears to have DontDelete set on it, which of course it shouldn&#8217;t have:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">x</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">delete</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">x</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// TypeError: Object doesn't support this action</span>
    <span style="color: #000066; font-weight: bold;">typeof</span> x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;number&quot; (still exists, wasn't deleted as it should have been!)</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">delete</span> x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// TypeError: Object doesn't support this action</span>
    <span style="color: #000066; font-weight: bold;">typeof</span> x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;number&quot; (wasn't deleted again)</span></pre></div></div>

<p>Now, contrary to what one would think, undeclared assignments (those that should create a property on global object) <strong>do create deletable properties</strong> in IE:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    x <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">delete</span> x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
    <span style="color: #000066; font-weight: bold;">typeof</span> x<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;undefined&quot;</span></pre></div></div>

<p>But if you try to delete such property by referecing it via <code>this</code> in Global code (<code>delete this.x</code>), a familiar error pops up:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    x <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">delete</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">x</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// TypeError: Cannot delete 'this.x'</span></pre></div></div>

<p>If we were to generalize this behavior, it would appear that <code>delete this.x</code> from within Global code never succeeds. When property in question is created via explicit assignment (<code>this.x = 1</code>), <code>delete</code> throws one error; when property is created via undeclared assignment (<code>x = 1</code>) or via declaration (<code>var x = 1</code>), <code>delete</code> throws another error.</p>
<p><code>delete x</code>, on the other hand, only throws error when property in question is created via explicit assignment — <code>this.x = 1</code>. If a property is created via declaration (<code>var x = 1</code>), deletion simply never occurs and <code>delete</code> correctly returns <code>false</code>. If a property is created via undeclared assignment (<code>x = 1</code>), deletion works as expected.</p>
<p>
    I was <a href="http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/22e6b2d147f57ee5/dda4dee3390fa71a">pondering about this issue back in September</a>, and <a href="http://dhtmlkitchen.com/">Garrett Smith</a> suggested that in IE <cite>&#8220;The global variable object is implemented as a JScript object, and the global object is implemented by the host</cite>. Garrett used <a href="http://blogs.msdn.com/ericlippert/archive/2005/05/04/414684.aspx">Eric Lippert&#8217;s blog entry</a> as a reference.<br />
    We can somewhat confirm this theory by performing few tests. Note how <code>this</code> and <code>window</code> seem to reference same object (if we can believe <code>===</code> operator), but Variable object (the one on which function is declared) is different from whatever <code>this</code> references.
  </p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #009966; font-style: italic;">/* in Global code */</span>
    <span style="color: #003366; font-weight: bold;">function</span> getBase<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
    getBase<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getBase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getBase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getBase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
    window.<span style="color: #660066;">getBase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getBase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
    window.<span style="color: #660066;">getBase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> getBase<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// false</span></pre></div></div>

<h3 id="misconceptions">Misconceptions</h3>
<p>
    The beauty of understanding why things work the way they work can not be underestimated. I&#8217;ve seen few misconceptions on the web related to misunderstanding of <code>delete</code> operator. For example, there&#8217;s <a href="http://stackoverflow.com/questions/1596782/how-to-unset-a-javascript-variable/1596889#1596889">this answer on Stackoverflow</a> (with surprisingly high rating), confidently explaining how <cite>&#8220;delete is supposed to be no-op when target isn&#8217;t an object property&#8221;</cite>. Now that we understand the <strong>core of <code>delete</code> behavior</strong>, it becomes pretty clear that this <strong>answer is rather inaccurate</strong>. <code>delete</code> doesn&#8217;t differentiate between variables and properties (in fact, for <code>delete</code>, those are all References) and really only cares about DontDelete attribute (and property existence).
  </p>
<p>
    It&#8217;s also interesting to see how misconceptions bounce off of each other, where in the very same thread someone first suggests to just delete variable (which won&#8217;t work unless it&#8217;s declared from within <code>eval</code>), and another person <a href="http://stackoverflow.com/questions/1596782/how-to-unset-a-javascript-variable/1596790#comment-1461494">provides a wrong correction</a> how it&#8217;s possible to delete variables in Global code but not in Function one.
  </p>
<p>Be careful with Javascript explanations on the web, and ideally, always seek to understand the core of the issue ;)</p>
<h3 id="delete_and_host_objects">`delete` and host objects</h3>
<p>An algorithm for <code>delete</code> is specified roughtly like this:</p>
<ol style="margin-bottom:2em;">
<li>If operand is not a reference, return <code>true</code></li>
<li>If object has no <strong>direct property</strong> with such name, return <code>true</code> (where, as we now know, object can be Activation object or Global object)</li>
<li>If property exists but has DontDelete, return <code>false</code></li>
<li>Otherwise, remove property and return <code>true</code></li>
</ol>
<p>
    However, behavior of <strong><code>delete</code> operator with host objects can be rather unpredictable</strong>. And there&#8217;s actually nothing wrong with that: host objects are allowed (by specification) to implement any kind of behavior for operations such as read (internal [[Get]] method), write (internal [[Put]] method) or delete (internal [[Delete]] method), among few others. This allowance for custom [[Delete]] behavior is what makes host objects so chaotic.
  </p>
<p>
    We&#8217;ve already seen some IE oddities, where deleting certain objects (which are apparently implemented as host objects) throws errors. Some versions of Firefox throw when trying to delete <code>window.location</code>. You can&#8217;t trust return values of delete either, when it comes to host objects; take a look at what happens in Firefox:
  </p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #009966; font-style: italic;">/* &quot;alert&quot; is a direct property of `window` (if we were to believe `hasOwnProperty`) */</span>
    window.<span style="color: #660066;">hasOwnProperty</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'alert'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">delete</span> window.<span style="color: #000066;">alert</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
    <span style="color: #000066; font-weight: bold;">typeof</span> window.<span style="color: #000066;">alert</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;function&quot;</span></pre></div></div>

<p>
    Deleting <code>window.alert</code> returns <code>true</code>, even though there&#8217;s nothing about this property that should lead to such result. It resolves to a reference (so can&#8217;t return <code>true</code> on the first step). It&#8217;s a direct property of a <code>window</code> object (so can&#8217;t return <code>true</code> on a second step). The only way <code>delete</code> could return <code>true</code> is after reaching step 4 and actually deleting a property. Yet, property is never deleted.
  </p>
<p>The moral of the story is to <strong>never trust host objects</strong>.</p>
<h3 id="es5_strict_mode">ES5 strict mode</h3>
<p>So what does strict mode of <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMAScript 5th edition</a> bring to the table? Few restrictions are being introduced. SyntaxError is now thrown when expression in <code>delete</code> operator is a direct reference to a variable, function argument or function identifier. In addition, if property has internal [[Configurable]] == false, a TypeError is thrown:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>foo<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #3366CC;">&quot;use strict&quot;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// enable strict mode within this function</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> bar<span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">function</span> baz<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">delete</span> foo<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// SyntaxError (when deleting argument)</span>
    <span style="color: #000066; font-weight: bold;">delete</span> bar<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// SyntaxError (when deleting variable)</span>
    <span style="color: #000066; font-weight: bold;">delete</span> baz<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// SyntaxError (when deleting variable created with function declaration)</span>
&nbsp;
    <span style="color: #009966; font-style: italic;">/* `length` of function instances has { [[Configurable]] : false } */</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">delete</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// TypeError</span>
&nbsp;
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>In addition, deleting undeclared variable (or in other words, unresolved Referece) throws SyntaxError as well:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #3366CC;">&quot;use strict&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">delete</span> i_dont_exist<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// SyntaxError</span></pre></div></div>

<p>This is somewhat similar to the way undeclared assignment in strict mode behaves (except that ReferenceError is thrown instead of a SyntaxError):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #3366CC;">&quot;use strict&quot;</span><span style="color: #339933;">;</span>
    i_dont_exist <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// ReferenceError</span></pre></div></div>

<p>As you now understand, all these restrictions somewhat make sense, given how much confusion deleting variables, function declarations and arguments causes. Instead of silently ignoring deletion, strict mode takes more <strong>agressive and descriptive measures</strong>.</p>
<h3 id="summary">Summary</h3>
<p>This post turned out to be quite lengthy, so I&#8217;m not going to talk about things like removing array items with <code>delete</code> and what the implications of it are. You can always refer to MDC article <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/delete_Operator#section_5">for that particular explanation</a> (or read specs and experiment yourself).</p>
<p>Here&#8217;s a short summary of how deletion works in Javascript:</p>
<ul>
<li>Variables and function declarations are properties of either Activation or Global objects.</li>
<li>Properties have attributes, one of which — DontDelete — is responsible for whether a property can be deleted.</li>
<li>Variable and function declarations in <strong>Global and Function code</strong> always create properties <strong>with DontDelete</strong>.</li>
<li><strong>Function arguments</strong> are also properties of Activation object and are created <strong>with DontDelete</strong>.</li>
<li>Variable and function declarations in <strong>Eval code</strong> always create properties <strong>without DontDelete</strong>.</li>
<li><strong>New properties</strong> are always created with empty attributes (and so <strong>without DontDelete</strong>).</li>
<li><strong>Host objects</strong> are allowed to react to deletion <strong>however they want</strong>.</li>
</ul>
<p>If you&#8217;d like to get more familiar with things described here, please refer to <a href="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf">ECMA-262 3rd edition specification</a>.</p>
<p>I hope you enjoyed this overview and learned something new. Any questions, suggestions and corrections are as always welcomed.</p>
</div>
<div class="tweetmeme_button" style="float: right; margin-left: 30px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fperfectionkills.com%2Funderstanding-delete%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fperfectionkills.com%2Funderstanding-delete%2F&amp;source=kangax&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8628792cef804c13af5f8ae4e1ba60e3" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/understanding-delete/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>Optimizing HTML</title>
		<link>http://perfectionkills.com/optimizing-html/</link>
		<comments>http://perfectionkills.com/optimizing-html/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 16:02:37 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[optimizations]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=60</guid>
		<description><![CDATA[

    #optimizing-html h4 { font-size: 1em; }
    #optimizing-html { margin-bottom: 2em; }
  

Why clean markup?
Markup smells
Additional optimizations
Agressive optimizations
When things go wrong
Antipatterns
Tools
Future considerations

Why clean markup?
Client-side optimization is getting a lot of attention lately, but some of its basic aspects seem to go unnoticed. If you look carefully at pages [...]]]></description>
			<content:encoded><![CDATA[<div id="optimizing-html">
<style type="text/css" media="screen">
    #optimizing-html h4 { font-size: 1em; }
    #optimizing-html { margin-bottom: 2em; }
  </style>
<ol>
<li><a href="#why_clean_markup">Why clean markup?</a></li>
<li><a href="#markup_smells">Markup smells</a></li>
<li><a href="#additional_optimizations">Additional optimizations</a></li>
<li><a href="#agressive_optimizations">Agressive optimizations</a></li>
<li><a href="#when_things_go_wrong">When things go wrong</a></li>
<li><a href="#antipatterns">Antipatterns</a></li>
<li><a href="#tools">Tools</a></li>
<li><a href="#future_considerations">Future considerations</a></li>
</ol>
<h3 id="why_clean_markup">Why clean markup?</h3>
<p>Client-side optimization is getting a lot of attention lately, but some of its basic aspects seem to go unnoticed. If you look carefully at pages on the web (even those that are <a href="http://bing.com">supposed to be highly optimized</a>), it&#8217;s easy to spot a good amount of <strong>redundancies, and inefficient or archaic structures</strong> in their markup. All this baggage adds extra weight to pages that are supposed to be as light as possible.</p>
<p>The reason to keep documents clean is not so much about faster load times, as it is about <strong>having a solid and robust foundation</strong> to build upon. Clean markup means better accessibility, easier maintenance, and good search engine visibility. Smaller size is just a property of clean documents, and another reason to keep them this way.</p>
<p>In this post, we&#8217;ll take a look at HTML optimization: removing some of the common markup smells; reducing document size by getting rid of redundant structures, and employing minification techniques. We&#8217;ll look at currently available minification tools, and analyze what they do wrong and right. We&#8217;ll also talk about what can be done in a future.</p>
<h3 id="markup_smells">Markup smells</h3>
<p>So what are the most common offenders?</p>
<h4 id="1_html_comments_in_scripts">1. HTML comments in scripts</h4>
<p>One of the <a href="http://www.google.com/codesearch?q=%2F%2F--%3E">gross redundanies</a> nowadays is inclusion of HTML comments &mdash; <code>&lt;!-- --&gt;</code> &mdash; in script blocks. There&#8217;s not much to say here, except that browsers that actually need this error-prevention measure (such as <a href="http://www.javascripttoolbox.com/bestpractices/#comments">&#8216;95 Netscape 1.0</a>) are pretty much extinct. Comments in scripts are just an unnecessary baggage and should be removed ferociously.</p>
<h4 id="2_cdata_8230_sections">2. &lt;![CDATA[ &#8230; ]> sections</h4>
<p>Another often needless error-prevention measure is inclusion of CDATA blocks in SCRIPT elements:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #006600; font-style: italic;">//&lt;![CDATA[</span>
      ...
    <span style="color: #006600; font-style: italic;">//]]&gt;</span>
  <span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<p>It&#8217;s a noble goal that falls short in reality. While CDATA blocks are a perfectly good way to prevent XML processor from recognizing &lt; and &amp; as start of markup, it is only the case in true XHTML documents &mdash; those that are served with &#8220;application/xhtml+xml&#8221; content-type. Majority of the web is still served as &#8220;text/html&#8221; (since, for example, IE doesn&#8217;t understand XHTML to this date), and so is <strong>parsed as HTML by the browsers</strong>, not as XML. </p>
<p>Unless you&#8217;re serving documents as &#8220;application/xhtml+xml&#8221;, there&#8217;s little reason to  have CDATA sections hanging around. Even if you&#8217;re planning to use xhtml in a future, it might make sense to remove unnecessary weight from the document, and only add it later, when actually needed.</p>
<p>And, of course, an ultimate solution here is to avoid inline scripts altogether (to take advantage of external scripts caching).</p>
<h4 id="3_onclick_onmouseover_etc">3. onclick=&#8221;&#8230;&#8221;, onmouseover=&#8221;&#8220;, etc.</h4>
<p>There are some valid use cases for intrinsic event attributes, such as for performance reasons or to target ancient browsers (although, I&#8217;m not aware of any environment that would understand event attributes &mdash; <code>onclick="..."</code>, and not property-based assignments &mdash; <code>element.onclick = ...</code>). Besides well-known reasons to avoid them, such as separation of concerns and reusability, there&#8217;s a matter of markup pollution. <strong>By moving event logic to external script, we can take advantage of that script&#8217;s caching</strong>. Event handler logic doesn&#8217;t need to be transferred to client every time document is requested.</p>
<h4 id="4_onclick_javascript">4. onclick=&#8221;javascript:&#8230;&#8221;</h4>
<p>An interesting confusion of javascript: pseudo protocol and intrinsic event handlers results in this redundant mix (<a href="http://www.google.com/codesearch?q=%5Cs%2Bon%5Cw%2B%3D%5B'%22%5Djavascript%3A">with 106,000 (!) occurrences</a>). The truth is that entire contents of event handler attribute become a body of a function. That function then serves as an event handler (usually, after <a href="http://www.jibbering.com/faq/names/event_handler.html">having its scope augmented</a> to include some or all of the ancestors and element itself). &#8220;javascript:&#8221; addition merely <strong>becomes an unnecessary</strong> <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Statements/label">label</a> and <strong>rarely serves any purpose</strong>.</p>
<h4 id="5_href_javascript_void">5. href=&#8221;javascript:void(0)&#8221;</h4>
<p>Continuting with &#8220;javascript:&#8221; pseudo protocol, there&#8217;s an infamous <a href="http://www.google.com/codesearch?q=href%3D%5B'%22%5Djavascript%3A%5Cs*void%5C(0%5C)%3B%3F%5B'%22%5D"><code>href="javascript:void(0)"</code></a> snippet, as a way to prevent default anchor behavior. This terrible practice of course makes anchor completely inacessible when Javascript is disabled/not available/errors out. It should go without saying that ideal solution is to include proper url in href, and stop default anchor behavior in event handler. If, on the other hand, anchor element is created dynamically, and is then inserted into a document (or is hidden initially, then shown via Javascript), plain <code>href="#"</code> is a leaner and faster alternative to &#8220;javascript:&#8221; version.</p>
<h4 id="6_style">6. style=&#8221;&#8230;&#8221;</h4>
<p>There&#8217;s nothing inherently wrong with style attribute, except that by moving its contents to an external stylesheet, we can take advantage of resource caching. This is similar to avoiding event attributes, mentioned earlier. Even if you only need to style one particular element and are not planning to reuse its styles, remember that style information has to be transferred every time document is requested. Moving style to external resouce prevents this, as stylesheet is transferred once and then cached on a client.</p>
<h4 id="7_script_language_javascript">7. &lt;script language=&#8221;Javascript&#8221; &#8230; ></h4>
<p>Probably one of the most misunderstood attributes is SCRIPT&#8217;s &#8220;language&#8221;. This attribute is so archaic that <strong><a href="http://www.w3.org/TR/html4/interact/scripts.html#h-18.2.1">it was already deprecated</a> in 1999 (!), 10 years ago</strong>, when HTML 4.01 became an official recommendation. There&#8217;s absolutely <strong>no reason to use this attribute</strong>, except for the rare cases when <a href="http://bclary.com/2004/08/27/javascript-version-incompatibilities">language version needs to be specified</a> (and even that is somewhat unreliable and should probably be avoided if possible).</p>
<h4 id="8_script_charset">8. &lt;script charset=&#8221;&#8230;&#8221; &#8230; ></h4>
<p>Another misunderstanding of SCRIPT element is that with charset attribute. Sometimes I see documents that include this kind of markup:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span> charset<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;UTF-8&quot;</span><span style="color: #339933;">&gt;</span>
    ...
  <span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<p>The thing is that charset attribute only really makes sense on &#8220;external&#8221; SCRIPT elements &mdash; those that have &#8220;src&#8221; attribute. HTML 4.01 even says:</p>
<p><em>Note that the charset attribute refers to the character encoding of the script designated by the src attribute; it does not concern the content of the SCRIPT element.</em></p>
<p>Testing shows that actual browsers behavior also matches specs in this regard.</p>
<p>Searching for this pattern, <a href="http://www.google.com/codesearch?q=%3Cscript(%5Cs%2Blanguage%3D%5B'%22%5D%5B%5E'%22%5D%2B%5B'%22%5D)%3F%5Cs%2Btype%3D%5B'%22%5Dtext%2Fjavascript%5B'%22%5D%5Cs%2Bcharset%3D%5B'%22%5D%5B%5E'%22%5D%2B%5B'%22%5D%5Cs*%3E">reveals about 2000 occurrences</a>. Not suprising, given that even popular apps like Textmate include <a href="http://github.com/textmate/html.tmbundle/blob/master/Snippets/XHTML%20%3Cscript%3E.plist">wrong usage of charset</a>.</p>
<h3 id="additional_optimizations">Additional optimizations</h3>
<p>We&#8217;ve covered some of the bad practices, that almost always have to be avoided. But there&#8217;s still more ahead, and that &#8220;more&#8221; is <strong>removing redundant parts</strong>. Optimizations explained below are often questionable, as they <strong>compromise clarity for size</strong>. Therefore I include them here not as a recommendation, but merely as an option. Employ with careful consideration.</p>
<h4 id="1_style_media_all">1. &lt;style media=&#8221;all&#8221; &#8230;></h4>
<p>HTML 4.01 defines media attribute on STYLE elements, as a way of targeting specific medium &mdash; screen, print, handheld, and so on. One of the possible values for media is &#8220;all&#8221;, which also happens to be a de-facto standard among modern (and not so modern) browsers. If you find yourself using <code>media="all"</code>, it should be <strong>safe to just omit it</strong> and let browser set value implicitly.</p>
<p>Interestingly, HTML 4.01 states that <a href="http://www.w3.org/TR/html401/present/styles.html#edef-STYLE">default value for media is &#8220;screen&#8221;</a>. However, none of the browsers I tested <sup class="reference"><a href="#media-attribute-tested-browsers">[1]</a></sup> implement it as per specs, and default to &#8220;all&#8221; instead. This is probably why <a href="http://www.w3.org/TR/html5/semantics.html#the-style-element">HTML 5 draft specifies default value as &#8220;all&#8221;</a> &mdash; to match actual browsers&#8217; behavior.</p>
<h4 id="2_form_method_get">2. &lt;form method=&#8221;get&#8221; &#8230;></h4>
<p>Another default value &mdash; GET &mdash; of FORM element&#8217;s <a href="http://www.w3.org/TR/REC-html40/interact/forms.html#adef-method">&#8220;method&#8221; attribute</a> is often <a href="http://www.google.com/codesearch?q=%3Cform(%5Cs%2Baction%3D%5B'%22%5D%5B%5E'%22%5D%2B%5B'%22%5D)%3F%5Cs%2Bmethod%3D%5B'%22%5Dget%5B'%22%5D">specified explicitly</a>. There&#8217;s no harm in dropping it, except for lesser clarity. Note that HTML 5 draft <a href="http://www.w3.org/TR/html5/forms.html#attr-fs-method">leaves this behavior untouched</a>.</p>
<h4 id="3_input_type_text">3. &lt;input type=&#8221;text&#8221; &#8230;></h4>
<p>INPUT element&#8217;s &#8220;type&#8221; defaults to &#8220;text&#8221; in both &mdash; <a href="http://www.w3.org/TR/html401/interact/forms.html#adef-type-INPUT">HTML 4.01</a> and <a href="http://www.w3.org/TR/html5/forms.html#attr-input-type">HTML 5 draft</a>. Dropping this attribute can result in substantial size savings on pages with lots of text fields.</p>
<h4 id="4_meta_http_equiv_content_type">4. &lt;meta http-equiv=&#8221;Content-type&#8221; &#8230;></h4>
<p>Specifying <a href="http://www.w3.org/TR/html401/charset.html#h-5.2.2">document&#8217;s character encoding</a> has always been a source of great confusion. Contrary to common belief, META element that specifies Content-type <strong>does not have higher priority</strong> over &#8220;Content-type&#8221; HTTP header that document is served with. When both &mdash; header and META element are specified, header takes precedence.</p>
<p>If you control server response and can set up Content-type header properly, it&#8217;s safe to omit META element. The only reason to keep it, is to <strong>specify encoding when document is viewed offline</strong>.</p>
<h4 id="5_a_id_name">5. &lt;a id=&#8221;&#8230;&#8221; name=&#8221;&#8230;&#8221; &#8230;></h4>
<p>The main reason &#8220;name&#8221; attribute is still used together with &#8220;id&#8221; is for compatibility with ancient browsers (e.g. Netscape 4). Those couldn&#8217;t link to anchors by &#8220;id&#8221;, so &#8220;name&#8221; had to be used. If you have elements with pairing name/id&#8217;s, and don&#8217;t care about ancient browsers, feel free to get rid of this archaic pattern.</p>
<p>Watch out for any side effects. If you&#8217;re referencing elements by name in scripts (<code>document.getElementsByName</code>, <code>document.evaluate</code>, <code>document.querySelectorAll</code>, etc.), replacing name&#8217;s with id&#8217;s might break things. Also remember that <code>document.anchors</code> <a href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-7577272">only returns elements with name attributes</a>.</p>
<h4 id="6_doctype_html">6. &lt;!doctype html></h4>
<p>A little more than a year ago, <a href="http://www.dustindiaz.com/skinny-on-doctypes/">Dustin Diaz prposed to use HTML 5 doctype</a>, as a way to cut down on document size. This is not a major optimization, but if you don&#8217;t care about validation and need to squeeze every single byte out of the page, using <code>&lt;!doctype html&gt;</code> is a viable option. <a href="http://hsivonen.iki.fi/doctype/#ie8modes">Tests</a> <a href="http://themaingate.net/dev/html/all-you-need-is-doctype-html">revealed</a> that this fancy doctype triggers standards mode in a large variety of browsers.</p>
<h3 id="agressive_optimizations">Agressive optimizations</h3>
<p>If you&#8217;re still craving for more, here are few extreme ideas. Some of these (e.g. omitting optional tags) have been <a href="http://code.google.com/speed/articles/optimizing-html.html">circulating around</a> for a while. Others I haven&#8217;t heard mentioned. Even though these might seem way too obtrusive, note that <strong>none of them really invalidate a document</strong>. That is if document is in HTML, not XHTML. But you&#8217;re <a href="http://hixie.ch/advocacy/xhtml">serving documents as HTML</a> anyway, don&#8217;t you? ;)</p>
<ol style="margin-left:2em">
<li>Remove HTML comments</li>
<li>Remove/collapse whitespace</li>
<li>Remove optional closing tags (<code>&lt;p&gt;foo&lt;/p&gt;</code> &rarr; <code>&lt;p&gt;foo</code>)</li>
<li>Remove quotes around attribute values, when allowed (<code>&lt;p class="foo"&gt;</code> &rarr; <code>&lt;p class=foo&gt;</code>)  </li>
<li>Remove optional values from boolean attributes (<code>&lt;option selected="selected"&gt;</code> &rarr; <code>&lt;option selected&gt;</code>)</li>
<li>Munge inline styles, inline scripts and event attributes (if it&#8217;s not possible to remove them)</li>
<li>Munge classes and ids (needs to be in sync with scripts and style declarations)</li>
<li>Strip scheme names off of URLs (<code>http://example.com</code> &rarr; <code>//example.com</code>)</li>
</ol>
<h3 id="but_we_have_compression">But we have compression!</h3>
<p>Do all of these optimizations even matter when document is compressed? Doesn&#8217;t gzip eliminate most of the markup overhead? After all, it&#8217;s a textual format we&#8217;re talking about!</p>
<p><strong>It still matters.</strong></p>
<p>First of all, it&#8217;s good to remember that <a href="http://www.stevesouders.com/blog/2009/11/11/whos-not-getting-gzip/">not everyone is getting gzip</a>. This is very sad, but the good thing is that in such cases HTML optimization plays even more significant role.</p>
<p>Second, even if document is served compressed, there are still savings of 5-10KB <strong>after compression</strong> (on an average document). Savings are even bigger with large documents. This might not seem like a lot, but in reality <a href="http://www.phpied.com/the-performance-business-pitch/">every byte counts</a>.</p>
<p>As an example of compressing large document, I munged unofficial HTML version of <a href="http://bclary.com/2004/11/07/">ECMA-262, 3rd edition specs</a>, which originally weighed about 750KB (131KB gzipped), to 606KB (115KB gzipped). That&#8217;s a saving of <strong>16 KB after gzipping</strong>, simply by removing whitespace, comments, attribute quotes and optional tags. You can see that <a href="http://yura.thinkweb2.com/ecma/">optimized version</a> looks the same as the old one.</p>
<p>Finally, optimizations like stripping whitespace and comments actually make resulting document tree lighter, potentially improving page rendering performance.</p>
<h3 id="when_things_go_wrong">When things go wrong</h3>
<p>As with any optimization, it&#8217;s very easy to get carried away. <a href="http://www.antssoft.com/htmlcompact/index.htm">HTML Compact</a> is a good example of HTML compression taken too far. This wonderful Windows app takes &#8220;unique&#8221; approach at compressing HTML&#8230; by writing it into a document via Javascript.</p>
<p>Turning this perfectly clean document:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">    &lt;html&gt;
      &lt;head&gt;
        &lt;title&gt;&lt;/title&gt;
      &lt;/head&gt;
      &lt;body&gt;
        &lt;div&gt;
          &lt;ul&gt;
            &lt;li&gt;foo&lt;/li&gt;&lt;li&gt;bar&lt;/li&gt;&lt;li&gt;baz&lt;/li&gt;
            &lt;!-- few more dozens of list elements ... --&gt;
          &lt;/ul&gt;
        &lt;/div&gt;
      &lt;/body&gt;
    &lt;/html&gt;</pre></div></div>

<p>into this mess:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">  &lt;!--hcpage status=&quot;compressed&quot;--&gt;
  &lt;html&gt;
    &lt;head&gt;
      &lt;SCRIPT LANGUAGE=&quot;JavaScript&quot; SRC=&quot;hc_decoder.js&quot;&gt;&lt;/SCRIPT&gt;
      &lt;title&gt;&lt;/title&gt;
    &lt;/head&gt;
    &lt;BODY&gt;
      &lt;NOSCRIPT&gt;To display this page you need a browser with JavaScript support.&lt;/NOSCRIPT&gt;
      &lt;SCRIPT LANGUAGE=&quot;JavaScript&quot;&gt;
        &lt;!--
          hc_d0(&quot;Mv#d|\x3C:,&amp;c@w4YFAtD1 [... and so on, another couple hundreds of characters ...]&quot;);
        //--&gt;
      &lt;/SCRIPT&gt;
    &lt;/BODY&gt;
  &lt;/html&gt;</pre></div></div>

<p>Needless to say, this kind of &#8220;optimization&#8221; should never be performed in the public web. Unless the intention is to make documents inacessible to users and search engines. And it hurts me seeing those NOSCRIPT elements, which fall short in clients behind <strong>Javascript-blocking firewalls</strong>. Bad idea, bad execution.</p>
<h3 id="antipatterns">Antipatterns</h3>
<p>Previous snippet was a good example of optimization anti-pattern. There are, however, few more you should be aware of:</p>
<h4 id="1_removing_doctype">1. Removing doctype</h4>
<p><a href="http://www.alentum.com/ahc/">HTML Compresor</a> has an option &mdash; on by default &mdash; to strip doctype. I can&#8217;t think of a case where stripping it would be beneficial. On a contrary, missing doctype <strong>triggers quirks mode</strong>, and as a result, wreaks havoc on a page layout and behavior. Doctypes should be left alone, or instead, replaced with a shorter &mdash; HTML 5 &mdash; version.</p>
<h4 id="2_replacing_strong_with_b_and_em_with_i">2. Replacing STRONG with B and EM with I</h4>
<p>Another harmful option in the same HTML Compressor is to replace elements with their shorter &#8220;alternatives&#8221;. The problem here is that B is not really an alternative to STRONG. Neither is I a replacement to EM. STRONG and EM elements have <strong>semantic meaning &mdash; emphasis</strong>, whereas B and I are simply font-style elements; They affect text rendering, but carry no semantic meaning.</p>
<p>Even though browsers usually display these elements identically, screen readers and search engines very much understand the difference.</p>
<h4 id="3_removing_title_alt_attributes_and_label_elements">3. Removing title, alt attributes, and LABEL elements.</h4>
<p>A good rule of thumb is to <strong>never optimize in exchange of accessibility</strong>. You might be tempted to remove that optional &#8220;alt&#8221; attribute on IMG elements, or &#8220;title&#8221; on anchors, but saving few dozens of bytes is really not worth often-critical accessibility loss.</p>
<h3 id="tools">Tools</h3>
<p>It&#8217;s more or less trivial to <strong>automate most of the tweaks</strong> from &#8220;additional optimizations&#8221; section. There already exist tools that strip comments, whitespaces, and remove quotes around attribute values. But these are still in their infancy and perform a very limited set of optimizations. We can definitely do better.</p>
<p>A couple of months ago, <a href="http://mediumexposure.com/">hakunin</a> and I started working on a similar, <a href="http://github.com/maxim/html_press">Ruby-based compressor</a>, but never had a chance to finish it.</p>
<p>So what do we have so far?</p>
<ol>
<li>
<p style="margin-bottom:0"><a href="http://www.alentum.com/ahc/">Absolute HTML Compressor</a> (desktop, windows)</p>
<p>Does great job, but only after turning off options like stripping doctype and replacing STRONG with I.</p>
</li>
<li>
<p style="margin-bottom:0"><a href="http://www.antssoft.com/htmlcompact/index.htm">HTML Compact</a> (desktop, windows)</p>
<p>Makes document inaccessible. <strong>Avoid</strong>.</p>
</li>
<li>
<p style="margin-bottom:0"><a href="http://download.cnet.com/HTML-Compressor/3000-10247_4-10871401.html">HTML Compressor</a> (desktop, windows)</p>
<p>Only removes whitespace, and even in whitespace-sensitive elements, such as PRE. <strong>Not very useful</strong>.</p>
</li>
<li>
<p style="margin-bottom:0"><a href="http://mailmarkup.org/prettydiff/prettydiff.html">Pretty Diff</a> (web-based)</p>
<p>Doesn&#8217;t have option to completely remove whitespaces (only collapses them). Doesn&#8217;t perform any optimizations except collapsing whitespace and removing newlines. Doesn&#8217;t respect whitespace-sensitive elements. <strong>Not very useful</strong>.</p>
</li>
<li>
<p style="margin-bottom:0"><a href="http://code.google.com/p/htmlcompressor/">htmlcompressor</a> (java-based)</p>
<p>Performs most of the optimizations described here (but doesn&#8217;t remove optional tags or shorten boolean attributes). Respects whitespace-sensitive elements. It is more or less <strong>best option</strong> at the moment.</p>
</li>
</ol>
<p>As you can see, current state of affairs is pretty disappointing. There seem to be no compression tools for Mac/Linux, and those for Windows are hardly useful.</p>
<h3 id="future_considerations">Future considerations</h3>
<p>Whereas munging and stripping can (and should) be done during production, markup smells is something that should <strong>never happen in the first place</strong>. Neither in production, nor in development. Not unless, for whatever reason, they are absolutely necessary.</p>
<p>
    Unsurprisingly, the best optimization one can do is often a manual one: changing document structure to avoid repeating classes on multiple elements (and instead moving them to parent element), or eliminating chunks that are not immediately needed, and instead loading them dynamically. Replacing miriads of <code>&lt;br></code>&#8217;s or <code>&amp;nbsp;</code>&#8217;s used inefficiently for presentational purposes, or that old table-based layout are other good examples of manual cleaning.
  </p>
<p>As far as all the other little tweaks, I expect more compression tools to appear in the near future, pushing size-reduction boundaries even further.</p>
<p>If you know more ways to optimize HTML, please share. I&#8217;d be glad to hear any questions, suggestions or corrections.</p>
<ol style="font-size:0.85em;border-top:1px dotted #aaa;padding-top:1em;margin-top:2em;padding-left:1.5em;">
<li id="media-attribute-tested-browsers">Tested browsers were:<br />
      <strong>Firefox</strong> 1, 1.5, 2, 3, 3.5;<br />
      <strong>Opera</strong> 7.54, 8.54, 9.27, 9.64, 10.10;<br />
      <strong>Safari</strong> 2.0.4, 3.0.4, 4;<br />
      <strong>Chrome</strong> 4 &mdash; on Mac OS X 10.6.2.<br />
      <strong>Internet Explorer</strong> 6, 7, 8 on Windows XP Pro SP2, and<br />
      <strong>Konqueror</strong> 4.3.2 on Ubuntu 9.10.
    </li>
</ol>
</div>
<div class="tweetmeme_button" style="float: right; margin-left: 30px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fperfectionkills.com%2Foptimizing-html%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fperfectionkills.com%2Foptimizing-html%2F&amp;source=kangax&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8628792cef804c13af5f8ae4e1ba60e3" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/optimizing-html/feed/</wfw:commentRss>
		<slash:comments>62</slash:comments>
		</item>
		<item>
		<title>Moved to perfectionkills.com</title>
		<link>http://perfectionkills.com/moved-to-perfectionkills-com/</link>
		<comments>http://perfectionkills.com/moved-to-perfectionkills-com/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 21:24:50 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/?p=52</guid>
		<description><![CDATA[This blog now lives at perfectionkills.com. No more weird, freakishly long URLs! Original RSS feed now points to a new domain, so things should just keep working there. 
Old address &#8212; thinkweb2.com/projects/prototype &#8212; redirects all requests to a new one, but if you link or reference this blog anywhere, please update address to a new [...]]]></description>
			<content:encoded><![CDATA[<p>This blog now lives at <a href="http://perfectionkills.com" title="new address of this blog">perfectionkills.com</a>. No more weird, freakishly long URLs! Original RSS feed now points to a new domain, so things should just keep working there. </p>
<p>Old address &mdash; thinkweb2.com/projects/prototype &mdash; redirects all requests to a new one, but if you link or reference this blog anywhere, please update address to a new one.</p>
<p>If you stumble upon any problems, I&#8217;d be glad to help.
<div class="tweetmeme_button" style="float: right; margin-left: 30px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fperfectionkills.com%2Fmoved-to-perfectionkills-com%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fperfectionkills.com%2Fmoved-to-perfectionkills-com%2F&amp;source=kangax&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8628792cef804c13af5f8ae4e1ba60e3" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/moved-to-perfectionkills-com/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>onload=function(){} considered harmful</title>
		<link>http://perfectionkills.com/onloadfunction-considered-harmful/</link>
		<comments>http://perfectionkills.com/onloadfunction-considered-harmful/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 01:45:19 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[ECMA-262]]></category>
		<category><![CDATA[don'ts]]></category>
		<category><![CDATA[strict-mode]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/onloadfunction-considered-harmful/</guid>
		<description><![CDATA[Harmful pattern
There seems to be a new pattern appearing on the web — attaching window load listener through undeclared assignment:

  onload = function&#40;&#41;&#123;
    /* ... */
  &#125;;

I&#8217;d like to explain why it&#8217;s a good idea to avoid it.
A conventional approach to perform this task is to explicitly assign to window.onload [...]]]></description>
			<content:encoded><![CDATA[<h3 id="harmful_pattern">Harmful pattern</h3>
<p>There seems to be a new pattern <a href="http://www.google.com/codesearch?q=%28^|%3B%29\s*onload\s*%3D\s*function">appearing</a> <a href="http://webreflection.blogspot.com/2009/06/inputfocus-something-really-annoying.html">on</a> <a href="http://webreflection.blogspot.com/2009/10/dom-node-proxy.html">the</a> <a href="http://stackoverflow.com/questions/1818501/javascript-how-is-function-x-different-from-x-function">web</a> — attaching window load listener through undeclared assignment:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #000066;">onload</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #009966; font-style: italic;">/* ... */</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>I&#8217;d like to explain why it&#8217;s a <strong>good idea to avoid it</strong>.</p>
<p>A conventional approach to perform this task is to explicitly assign to <code>window.onload</code> property. That is, not counting other means like DOM L2 methods — <code>addEventListener</code> (as well as proprietary <code>attachEvent</code>), or intrinsic event attributes — <code>&lt;body onload="..."&gt;</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  window.<span style="color: #000066;">onload</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #009966; font-style: italic;">/* ... */</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<h3 id="how_does_it_work">How does it work?</h3>
<p>A tempting &#8220;short&#8221; version takes advantage of <strong>Javascript loose nature</strong> with regards to variable declarations. In Javascript, assigning to undeclared variable actually creates a property on a Global Object — global property. Since Global Object in browsers is usually a <code>window</code> object (or at least it often behaves that way), undeclared assignment essentially results in creation of property on <code>window</code>. As long as Global Object and <code>window</code> are the same entity, <code>window.onload = ...</code> and <code>onload = ...</code> should have identical results. At least, that&#8217;s how it is in theory, and in practice there are more implications, as you will see later on.</p>
<p>So if two are identical, why would we ever prefer longer version?</p>
<p>Because shorter one <strong>relies on undeclared assignment</strong>.</p>
<h3 id="who_cares">Who cares?</h3>
<p>Undeclared assignments have been frowned upon for a long time, and rightfully so. Global variables declared locally are hard to maintain and generally cause confusion. It&#8217;s not always clear whether such assignments are intentional or simply an oversight. It is why validators like JSLint have been emiting warnings when encountering them.</p>
<h3 id="mshtml_peculiarities">MSHTML peculiarities</h3>
<p>Another reason to avoid undeclared assignments is due to rather destructive behavior of MSHTML DOM. When undeclared assignment happens in IE, an obscure error is thrown if identifier is named as id or name of one of the elements in a document:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  &lt;p id=&quot;foo&quot;&gt;&lt;/p&gt;
  &lt;form name=&quot;bar&quot; action=&quot;&quot;&gt;&lt;p&gt;&lt;/p&gt;&lt;/form&gt;
&nbsp;
  <span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #000066; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
      foo <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> 
    <span style="color: #000066; font-weight: bold;">catch</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      document.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// TypeError: Object doesn't support this property or method</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
      bar <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> 
    <span style="color: #000066; font-weight: bold;">catch</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      document.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// ReferenceError: Illegal assignment</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<p>Note that plain <strong>variable declarations</strong> in global scope, or <strong>explicit assignments</strong> have no such problems:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  &lt;p id=&quot;foo&quot;&gt;&lt;/p&gt;
  &lt;form name=&quot;bar&quot; action=&quot;&quot;&gt;&lt;p&gt;&lt;/p&gt;&lt;/form&gt;
&nbsp;
  <span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #003366; font-weight: bold;">var</span> foo <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// declares (and initializes) global `foo` variable</span>
    window.<span style="color: #660066;">foo</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// assigns to a &quot;foo&quot; property of `window` object</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">foo</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// assigns to a &quot;foo&quot; property of Global Object</span>
  <span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<h3 id="but_8220onload8221_is_different">But &#8220;onload&#8221; is different!</h3>
<p>Technically speaking, the case with <code>onload = function(){ }</code> can be considered an exception. After all, an intention to create global <code>onload</code> property is rather clear there. It&#8217;s also unlikely that there will be an element with such id/name (<strong>although, you never know!</strong>). There&#8217;s, however, another problem rising up, and that <strong>problem is strict mode</strong> of <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMA-262 5th edition</a> — a standard for an upcoming version of ECMAScript language, approved officially only few days ago.</p>
<h3 id="strict_what">Strict what?</h3>
<p>The premise of strict mode is to provide higher security level for an ECMAScript program (or part of it): avoid features that are considered error-prone or inefficient; employ stricter error checking; provide increased performance. One of such &#8220;stricter error checks&#8221; happens to be the one with undeclared assignments, which simply <strong>throw error</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #3366CC;">&quot;use strict&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #000066;">onload</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #006600; font-style: italic;">// ReferenceError</span>
    <span style="color: #009966; font-style: italic;">/* ... */</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  window.<span style="color: #000066;">onload</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #006600; font-style: italic;">// Works as expected</span>
    <span style="color: #009966; font-style: italic;">/* ... */</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Now, it&#8217;s worth mentioning that <strong>not all browsers would throw error</strong>. Some of them (e.g. WebKit) actually have properties corresponding to event handlers — such as &#8220;onload&#8221; — declared implicitly, before script execution occurs. Those that don&#8217;t — such as Firefox or Opera — would miserably fail.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #3366CC;">&quot;onload&quot;</span> <span style="color: #000066; font-weight: bold;">in</span> window<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true in WebKit, but not Firefox or Opera</span>
  window.<span style="color: #000066;">onload</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// `null` in WebKit, `undefined` in Firefox or Opera</span>
  <span style="color: #000066;">onload</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// `null` in WebKit, ReferenceError in Firefox or Opera</span></pre></div></div>

<h3 id="does_it_really_matter">Does it really matter?</h3>
<p>It&#8217;s good to understand that <strong>strict mode is not a requirement</strong>, but is merely an option. It is there to provide stricter rules for those who need it, and are willing to cope with (and enjoy) consequences. So if you are planning to make your code &#8220;strict&#8221;, don&#8217;t forget to avoid undeclared assignments — even as innocent-looking as &#8220;onload&#8221; ones.</p>
<div class="tweetmeme_button" style="float: right; margin-left: 30px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fperfectionkills.com%2Fonloadfunction-considered-harmful%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fperfectionkills.com%2Fonloadfunction-considered-harmful%2F&amp;source=kangax&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8628792cef804c13af5f8ae4e1ba60e3" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://perfectionkills.com/onloadfunction-considered-harmful/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
