<?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>Tue, 09 Mar 2010 17:48:35 +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>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>24</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>138</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>27</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>58</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>8</slash:comments>
		</item>
		<item>
		<title>Foxify bookmarklet</title>
		<link>http://perfectionkills.com/foxify-bookmarklet/</link>
		<comments>http://perfectionkills.com/foxify-bookmarklet/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 04:15:11 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[bookmarklet]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/foxify-bookmarklet/</guid>
		<description><![CDATA[Do you know which percentage of Firefox users are browsing your website with an oldish 2.x version? What about diminishing 3.x or even ancient 1.x and 1.5.x versions? Google Analytics &#8220;browser&#8221; reports, while being very helpful, make it somewhat hard to answer this particular question.
I made a simple bookmarklet (with a silly name) to report [...]]]></description>
			<content:encoded><![CDATA[<p>Do you know which percentage of Firefox users are browsing your website with an oldish 2.x version? What about diminishing 3.x or even ancient 1.x and 1.5.x versions? Google Analytics &#8220;browser&#8221; reports, while being very helpful, make it somewhat hard to answer this particular question.</p>
<p>I made a <a href="javascript:%20(function(){function%20hasParentWithClass(element,className){var%20reClassName=new%20RegExp('(?:\\s|^)'+className+'(?:\\s|$)');while((element=element.parentNode)){if(element&amp;&amp;reClassName.test(element.className))return%20true;}%20return%20false;}%20function%20getVersionTotal(element){var%20parentRow;while((element=element.parentNode)){if(element&amp;&amp;(element.tagName.toUpperCase()==='TR')){parentRow=element;break;}}%20for(var%20i=0,j=0,child,len=parentRow.childNodes.length;i&lt;len;i++){child=parentRow.childNodes[i];if(child.nodeType!==1)continue;if(j++==2)return%20parseInt(child.innerHTML.replace(/,/g,''));}}%20function%20countPercentages(){var%20total=0;for(var%20prop%20in%20versionTotals){total+=versionTotals[prop];}%20for(var%20prop%20in%20versionTotals){versionTotals[prop]+=('%20('+((versionTotals[prop]*100)/total).toFixed(2)+'%)');}}%20function%20padString(str,length){var%20numSpacesToPad;if(str.length&lt;length){numSpacesToPad=length-str.length;return%20str+new%20Array(numSpacesToPad+1).join('%20');}%20return%20str;}%20function%20displayTotals(){var%20str='';for(var%20name%20in%20versionTotals){str+=(padString(name,5)+':%20'+versionTotals[name]+'\n')}%20alert(str);}%20var%20anchors=document.getElementsByTagName('a'),i=anchors.length,el,match,majorVersion,color,bgColor;var%20versionTotals={'1':0,'1.5':0,'2':0,'3':0,'3.5+':0};while(i--){if(!hasParentWithClass((el=anchors[i]),'text_wrapper'))continue;if((match=el.innerHTML.match(/^\s*(\d\.\d)/))&amp;&amp;match[1]){majorVersion=parseFloat(match[1]);color='inherit';if(majorVersion&gt;=3.5){bgColor='lightgreen';versionTotals['3.5+']+=getVersionTotal(el);}%20else%20if(majorVersion&gt;=3){bgColor='yellow';versionTotals['3']+=getVersionTotal(el);}%20else%20if(majorVersion&gt;=2){bgColor='orange';versionTotals['2']+=getVersionTotal(el);}%20else%20if(majorVersion&gt;=1.5){bgColor='red';color='#fff';versionTotals['1.5']+=getVersionTotal(el);}%20else%20if(majorVersion&gt;=1){bgColor='black';color='#fff';versionTotals['1']+=getVersionTotal(el);}%20else%20continue;el.style.backgroundColor=bgColor;el.style.padding='0.5em';el.style.color=color;}}%20countPercentages();displayTotals();})();" title="Foxify bookmarklet">simple bookmarklet</a> (with a silly name) to report a percentage-based breakdown of Firefox visitors by version. Bookmarklet also color-codes each entry for easier navigation — Firefox 3.5 and later (such as currently beta 3.6 and alpha 3.7) in green; 3.x in yellow; 2.x in orange; 1.5.x in red, and finally 1.x — in black (you&#8217;ll be surprised, but yes, those dinosaurs still exist).</p>
<p>Colored entries make it really easy to spot old version or a group of browsers from particular series. On a screenshot below, for example, you can see 2.0.20 stand out with 1,072 visits; and total amount of all Firefox 2.x users being 3,209 — 3.78% of all visits. Knowing percentage of particular series should also make it easier to decide whether it makes sense to support it.</p>
<p>Don&#8217;t forget that if you need to analyze Safari versions, there&#8217;s <del>an app for that</del> a similar <a href="http://perfectionkills.com/safarify-bookmarklet/" title="Post about Safarify bookmarklet">Safarify bookmarklet</a>.</p>
<p>As usual, <a href="http://github.com/kangax/foxify" title="bookmarklet's repository on github">source (and latest version) is on github</a>. Hope you find it useful.</p>
<p><img src="http://yura.thinkweb2.com/screenshot_of_colored_results.png" alt="Screenshot of colored results">
<div class="tweetmeme_button" style="float: right; margin-left: 30px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fperfectionkills.com%2Ffoxify-bookmarklet%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fperfectionkills.com%2Ffoxify-bookmarklet%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/foxify-bookmarklet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sputniktests web runner</title>
		<link>http://perfectionkills.com/sputniktests-web-runner/</link>
		<comments>http://perfectionkills.com/sputniktests-web-runner/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 19:08:14 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[ECMA-262]]></category>
		<category><![CDATA[Sputniktests]]></category>
		<category><![CDATA[[[Class]]]]></category>
		<category><![CDATA[benchmark]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/sputniktests-web-runner/</guid>
		<description><![CDATA[

    #sputniktests-web-runner ul li { margin-bottom: 0; }
    #sputniktests-web-runner h2 { margin-bottom: 1em; }
    #sputniktests-web-runner h3 { font-size: 1em; }
    #sputniktests-web-runner h3 code { background: none; border: none; font-size: 1.25em; }
  

Intro
Why it doesn&#8217;t always matter
How runner works
Browser comparison
Notable deviations
Errors in test [...]]]></description>
			<content:encoded><![CDATA[<div id="sputniktests-web-runner">
<style type="text/css">
    #sputniktests-web-runner ul li { margin-bottom: 0; }
    #sputniktests-web-runner h2 { margin-bottom: 1em; }
    #sputniktests-web-runner h3 { font-size: 1em; }
    #sputniktests-web-runner h3 code { background: none; border: none; font-size: 1.25em; }
  </style>
<ul>
<li><a href="#intro" title="">Intro</a></li>
<li><a href="#why-it-doesnt-matter">Why it doesn&#8217;t always matter</a></li>
<li><a href="#how-runner-works" title="">How runner works</a></li>
<li><a href="#browser-comparison" title="">Browser comparison</a></li>
<li><a href="#notable-deviations" title="">Notable deviations</a></li>
<li><a href="#errors-in-test-suite" title="">Errors in test suite</a></li>
<li><a href="#future-work" title="">Future work</a></li>
</ul>
<h2 id="intro">Intro</h2>
<p><a href="http://code.google.com/p/sputniktests/" title="">Sputniktests</a> is an ECMA-262 conformance test suite made by Google. For those who don&#8217;t know, ECMA-262 is a standard behind well-known implementations like <a href="http://en.wikipedia.org/wiki/JScript" title="JScript">JScript</a>, <a href="http://en.wikipedia.org/wiki/JavaScript" title="JavaScript">JavaScript</a> and others. It&#8217;s what describes ECMAScript language.</p>
<p>Ever since <a href="http://blog.chromium.org/2009/06/launching-sputnik-into-orbit.html">Sputniktests release few months ago</a>, I wanted to see <strong>how various browsers conform to the standard</strong>. Unfortunately it wasn&#8217;t very easy to do so. The way test suite could be executed is by running a python script, passing it an executable file of implementation such as V8 or Rhino. It wasn&#8217;t possible to just check conformance of any browser, especially browser with implementation that can&#8217;t be run separately.</p>
<p>I realized that a &#8220;web runner&#8221; for Sputniktests would be a useful thing to have and <a href="http://kangax.github.com/sputniktests-webrunner/">made one</a>. In the end, it was a fun little exercise that made me understand ECMAScript language just a bit better.</p>
<p>  <a href="http://kangax.github.com/sputniktests-webrunner/" title="Sputniktests web runner"><br />
    <img src="http://yura.thinkweb2.com/sputniktests-webrunner.png" alt="Sputniktests screenshot" style="display:block"><br />
  </a></p>
<p>Web runner is merely a wrapper around original test suite, made fit to run in a browser environment. Its job is to execute tests sequentially and log any errors/failures in the process. When done, it reports elapsed time and number of errors.</p>
<h2 id="why-it-doesnt-matter">Why it doesn&#8217;t always matter</h2>
<p>Contrary to something like <a href="http://acid3.acidtests.org/" title="">Acid test</a>, <strong>Sputniktests is not immediately useful</strong>. Passing it fully does not necessarily make a browser more capable than the other one, with lower score. Many failures in modern browsers are rather insignificant from practical point of view and might not even affect any  real world applications.</p>
<p>But there&#8217;s still <strong>a huge value in a conformance test suite like this</strong>. By testing every single detail of ECMAScript implementation, Sputniktests could help minimize regressions, both — functional and performance ones. It could serve as an excellent foundation for creating a new ECMAScript implementation. And last, but not least, it could help browser implementors find actual valid bugs in browser engines.</p>
<p>There&#8217;s an important point to understand regarding test suite failures: not all of them can — or even should — be fixed, and here&#8217;s why:</p>
<h3>Proprietary extensions</h3>
<p>It is a well-known fact that specifications allows implementations to introduce proprietary extensions. JScript and JavaScript &#8482; have been doing this for years. JScript&#8217;s conditional comments and JavaScript&#8217;s getters/setters demonstrate it very well. Another famous example is the way <a href="http://yura.thinkweb2.com/named-function-expressions/#function-statements">function declarations are treated in statements</a>.
  </p>
<p>The point here is simple. <strong>Failure in Sputniktests can be the result of proprietary extension</strong> and might not even be considered a bug.</p>
<h3>ECMAScript 5th edition</h3>
<p>Another cause of &#8220;valid failures&#8221; might be the next edition of ECMAScript, currently draft. Some browsers have already started implementing parts of it and might fail to comply with 3rd edition that Sputniktests checks against. <a href="#for-in-undefined-null">For-in handling</a> is a good example of such &#8220;misunderstanding&#8221;.
  </p>
<h3>Backwards compatibility</h3>
<p>Finally, there&#8217;s always a beloved backwards compatibility to keep in mind. It might not be possible to fix otherwise valid bug/deviation due to this wonderful constraint.</p>
<h2 id="how-runner-works">How runner works</h2>
<p>Runner works very simply. First, a query of tests is initialized and populated with all of the 5000+ tests. Then, a table of tests to ignore is initialized and is later used for&#8230; ignoring certain conflicting or complex tests. Finally, runner starts picking tests from the query, with a certain interval in between — to keep UI functional during this rather intensive process. Note that interval can be changed on the main screen before starting test suite but defaults to 50ms.</p>
<p>For every test, runner creates a new iframe, inserts it into a current document and writes a script element into it. This is done <strong>to keep tests isolated from each other</strong>, so that one test wouldn&#8217;t affect environment of the next one. Once script is executed, a meta data is printed to the screen: name of current test, total number of errors/failures, elapsed time, etc. Iframe is then deleted.</p>
<p>Before adding actual test script to an iframe, runner first injects a complementary script into it. That script defines global $ERROR, $FAIL and $PRINT and simply proxies them to same-named functions of main (parent) document. When these methods are called, they write an output to main document log area.</p>
<h2 id="browser-comparison">Browser comparison</h2>
<p>So how do modern and not so modern browsers stand against standard? Here&#8217;s a comparison table (note that <strong>less score is better</strong> and that <strong>score represents total number of errors and failures</strong>):</p>
<p>  <img src="http://yura.thinkweb2.com/sputniktests_chart.png" alt="Sputniktests results chart" style="display:block"></p>
<p>We can see few interesting things here:</p>
<ul>
<li>Surprisingly, Opera 9.64 is a winner. Even more strange is that Opera 10 has some serious regressions and falls far far behind, joining ancient Safari 2.x</li>
<li>I was expecting Safari 4 to beat Firefox 3.5 (or 3.7), but it doesn&#8217;t even compare with Firefox 2.x</li>
<li>Firefox 3.7 (currently alpha) performs 1 point worse than Firefox 3.5</li>
<li>It&#8217;s amusing to see Internet Explorer results. The latest and greatest 8th version is practically identical to IE 5.5 (!!!). This hints at how fast bugs are being fixed in JScript.</li>
<li>Chrome 4 gets surprisingly low number (in between Firefox 3 and Firefox 2). I thought it would beat everyone else, considering that Sputniktests was originally developed to aid Chrome conform to the standard.</li>
<li>Out of all latest browsers (not considering regressed Opera 10), Konqueror gets the poorest score and probably needs to work on its compliance in the near future.</li>
</ul>
<h2 id="notable-deviations">Notable deviations</h2>
<p>Here are some of the bugs and quirks I noticed in few browsers. Each is accompanied with a short explanation.</p>
<h3 id="for-in-undefined-null"><strong>1) <code>for (var prop in null) { }</code></strong> <br /> <strong><code>for (var prop in undefined) { }</code></strong></h3>
<p>These statements should actually <strong>result in a <code>TypeError</code></strong>, and the explanation to that is pretty simple. During evaluation, an expression on the right hand side of <code>in</code> is being applied internal <code>ToObject</code> method. This internal method is the one that throws <code>TypeError</code> when given <code>null</code> or <code>undefined</code> value. </p>
<p>You might be wondering if <code>ToObject</code> is used anywhere else and has similar consequences? It does. Roughly, in 3 cases:</p>
<ul>
<li>foo[bar]</li>
<li>with (foo) &#8230;</li>
<li>for (bar in foo) &#8230;</li>
</ul>
<p>When <code>foo</code> evaluates to <code>null</code> or <code>undefined</code>, in any of these cases, <code>TypeError</code> is inevitable. Most browsers, however, throw error with first two statements, but <strong>not the last one</strong>. This is, arguably, a more useful behavior, even though technically, not ECMA-compliant. </p>
<p>Note that 5th edition of ECMAScript actually changes &#8220;for-in&#8221; to do exactly what most of the browsers currently do — not throw TypeError, but instead proceed as if <code>foo</code> was an empty object.</p>
<h3 id="number-u00A0"><strong>2) <code>Number('\u00A0') === 0</code></strong></h3>
<p>When Number is called as a function, it performs type conversion. String to number type conversion is expressed in rather involved algorithm, but one of the simplest rules there is that when string consists of a whitespace character (or is empty), the result is <code>0</code>. This means that both — <code>Number('')</code> and <code>Number(' ')</code> should evaluate to <code>0</code>. </p>
<p>Some browsers, however, fail to comply in regards to <strong>the notion of whitespace character</strong>. Passing plain <code>U+0020</code> does the job, but <code>U+00A0</code> (and <a href="http://perfectionkills.com/whitespace-deviations/">a whole slew of other ones</a>) often doesn&#8217;t. Instead, <code>NaN</code> is returned for what should really be a <code>0</code>.</p>
<h3 id="parsefloat-u205f"><strong>3) <code>parseFloat(&#8220;\u205F -1.1&#8221;)</code></strong></h3>
<p>Similar bug exists with handling of white space characters by <code>parseFloat</code>. Spec explains that <strong>any leading whitespace is ignored</strong> in input string. Something like <code>parseFloat('   2.5   ')</code> should result in <code>2.5</code>. And again, some implementations fail with rarer whitespace characters, such as <code>U+205F</code> or <code>U+1680</code>. Interestingly, only Opera is fully conforming here. Firefox and Webkit both fail one way or another.</p>
<h3 id="error-prototype-message"><strong>4) <code>Error.prototype.message</code></strong></h3>
<p>This one looks like a real bug in WebKit. WebKit throws &#8220;Unknown error&#8221; when merely attempting to access <code>Error.prototype.message</code>. Sputniktests actually managed to mess up here as well: test suite asserts that the property is an empty string, whereas specs say that <code>Error.prototype.message</code> is <strong>an implementation-dependent string</strong> (which means that it could as well be &#8220;foo-bar_BaZ&#8221;). Sputniktests need to check type of a property — <code>typeof Error.prototype.message == 'string'</code>, and WebKit needs to stop throwing error.</p>
<h3 id="evalerror-non-enumerable"><strong>5) <code>EvalError</code> and other <code>xxxError</code> ones are non-enumerable global properties</strong></h3>
<p>This one seems like a rather insignificant compliance. All properties of global object are specified to be non-enumerable (that is — have {DontEnum} internal attribute set on). However, at least WebKit enumerates over all of the global <code>EvalError</code>, <code>RangeError</code>, <code>SyntaxError</code>, etc.</p>
<h3 id="construct-and-prototype-of-builtins"><strong>6) <code>[[Construct]]</code> and <code>.prototype</code> of built-in objects</strong>.</h3>
<p>There&#8217;s a whole slew of failures in Firefox due to built-in objects having what they shouldn&#8217;t have — <code>prototype</code> property and [[Construct]] method. To remind you, [[Construct]] is an internal method that&#8217;s called when applying <code>new</code> operator to an object — usually a function. It is basically what makes certain objects &#8220;constructable&#8221;, and what every native function object has intrinsically. The failing built-ins are global methods like <code>parseInt</code>, <code>isNaN</code>, <code>encodeURI</code>, as well as properties of <code>Object.prototype</code>, <code>Array.prototype</code>, and so on. To quote specs:</p>
<p><em>&#8220;None of the built-in functions described in this section shall initially have a prototype property unless otherwise specified in the description of a particular function&#8221;</em></p>
<p>and:</p>
<p><em>&#8220;None of the built-in functions described in this section shall implement the internal [[Construct]] method unless otherwise specified in the description of a particular function.&#8221;</em></p>
<h3 id="typeof-new-regexp-function"><strong>7) <code>typeof new RegExp() === 'function'</code></strong></h3>
<p>This is probably one of the most famous WebKit deviations. As you might know, a large number of <strong>browsers make regex objects callable</strong>. Callable regular expressions allow to replace <code>/(a|b)/.exec('a')</code> with simply <code>/(a|b)/('a')</code>. I&#8217;m not sure where this non-standard behavior originates from, but it&#8217;s probably still kept around for backwards compatibility. </p>
<p>Interestingly, regex objects in WebKit seem to actually implement internal [[Call]] method. As per specs, any native object that implements [[Call]] should return &#8220;function&#8221; when applied <code>typeof</code> to, so WebKit merely follows the standard here. However, this little addition results in a side effect: regex objects are being reported as functions — <code>typeof /x/ == 'function'</code>. </p>
<p>Older Firefox (e.g. Firefox 2), by the way, behaves just like WebKit here.</p>
<h3 id="new-regexp-undefined"><strong>8) <code>new RegExp(undefined)</code></strong></h3>
<p>Another bug in Firefox is the way RegExp constructor treats pattern of <code>undefined</code> value. Specs mandate that when <code>undefined</code>, pattern should simply become an empty string (i.e. functionally identical to <code>new RegExp('')</code>). WebKit and Opera do just that, but Firefox converts <code>undefined</code> into its string representation — &#8220;undefined&#8221;, making regex behave as if it was created literally via <code>/undefined/</code>.</p>
<h3 id="search-empty-undefined"><strong>9) <code>"".search()</code> and <code>"--undefined--".search()</code></strong></h3>
<p>This one is related to a previous bug. The purpose of <code>String.prototype.search</code> is to find offset within the string where a given pattern matches. As usual, all is nice and well, until we start dealing with non-trivial input values.</p>
<p>When given a non-regex object as a first argument, <code>String.prototype.search</code> should apply <code>new RegExp()</code> on it. This means that <code>"".search()</code> is functionally identical to <code>"".search(new RegExp())</code>, where <code>undefined</code> value is being applied <code>new RegExp</code> on. This expression essentially matches empty regex against empty string. The result of <code>"".search()</code>, quite obviously, should be <code>0</code>, since empty regex (i.e. nothingness) matches at the very first position of empty string it&#8217;s being applied to. </p>
<p>Firefox, however, erroneously makes <code>/undefined/</code> out of <code>new RegExp()</code>, and fails to match empty string at <code>0th</code> position. For the very same reasons, it returns <code>2</code> in <code>"--undefined--".search()</code>, instead of correct <code>0</code>.</p>
<h3 id="substring-undefined"><strong>10) <code>"foo".substring(0, undefined);</code></strong></h3>
<p>Another weird quirk in Firefox is the way it handles second argument — ending position — of <code>String.prototype.substring</code>. Spec clearly states that when <code>undefined</code>, position is considered to be end of a string. For example, <code>"foobar".substring(0, 2)</code> should return <code>"fo"</code>, but <code>"foobar".substring(0)</code> — <code>"foobar"</code>, since end position is considered to be at the end of a string.</p>
<p>Firefox does this partially right, producing proper result when argument is missing — <code>"foobar".substring(0) === "foobar"</code>, but somehow fails to do the same, when passing <code>undefined</code> value explicitly — <code>"foobar".substring(0, undefined) === ""</code>.</p>
<h3 id="line-terminators-in-regex-literals"><strong>11) Line terminators in regex literals</strong></h3>
<p>An interesting quirk present in both — Firefox and Opera, but not in WebKit is related to regular expression literals. Spec makes it clear that <strong>regex literals are not allowed to have line terminators</strong> in their bodies. Not even when escaped with backslash. Firefox and Opera, however, seem to be perfectly fine with line terminators as long as those are escaped: <code>eval("/\\\u000A/")</code> results in an invalid regex literal that looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">/</span>\
<span style="color: #339933;">/</span></pre></div></div>

<h2 id="errors-in-test-suite">Test suite errors and oversights</h2>
<p>Sputniktests is a truly outstanding effort. I&#8217;m amazed at the amount of work that was put into it. However, the project is still in its infancy, and there are clearly some things that could be done better.</p>
<p>What striked me as being inconsistent and harmful is the way Sputniktests declares variables: sometimes using proper declarations (<code>var foo = 'bar'</code>), other times — using undeclared assignments (<code>foo = bar</code>). <strong>Undeclared assignments is a very bad practice</strong>, and there&#8217;s no reason to rely on it here or anywhere. It would be nice to see this changed in the future versions.</p>
<p>Other inconsistencies are with usage of $PRINT function. Sometimes it&#8217;s used to log additional information about tests, but not always.</p>
<p>There are cases when tests rely on compliance of other components and, as a result, <strong>give false positives</strong>. For example, a test for function expression in <code>for-in</code> statement assumes that <code>prototype</code> property of a function is enumerable:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>x <span style="color: #000066; font-weight: bold;">in</span> <span style="color: #003366; font-weight: bold;">function</span> __func<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;">0</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><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>x <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;prototype&quot;</span><span style="color: #009900;">&#41;</span> 
    <span style="color: #003366; font-weight: bold;">var</span> __reached <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;">if</span> <span style="color: #009900;">&#40;</span>__reached <span style="color: #339933;">!==</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    $ERROR<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#2: function expession inside of for-in expression is allowed'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Per specification, <code>prototype</code> property of function object is in fact enumerable (it only has {DontDelete} attribute set on). But Firefox, for example, makes <code>prototype</code> non-enumerable and so fails this test. It <strong>fails it erroneously</strong> because function expression in for-in statements — what this test is actually supposed to ensure — is allowed in Firefox just fine.</p>
<p>A similar case of false results happens when testing for <code>Array.prototype</code> compliance. <code>Array.prototype</code> should itself be an array object; its internal [[Class]] should be that of all array objects — &#8220;Array&#8221;. The test, unfortunately, checks this compliance by deleting <code>Array.prototype.toString</code>, then calling <code>toString</code> on <code>Array.prototype</code>, letting <code>Object.prototype.toString</code> propagate through and ensuring that [[Class]] of <code>Array.prototype</code> is &#8220;Array&#8221;.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">delete</span> Array.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">toString</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>Array.<span style="color: #660066;">prototype</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: #3366CC;">&quot;[object &quot;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;Array&quot;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;]&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  $ERROR<span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/* ... */</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Clients that have non-deletable <code>Array.prototype.toString</code> fail this test even with fully conforming <code>Array.prototype</code>. </p>
<p>It might be safer to use <code>call</code> here, but then clients with non-conforming <code>call</code> could result in false positives as well:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Is Array.prototype's [[Class]] an &quot;Array&quot;?</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</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>Array.<span style="color: #660066;">prototype</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #3366CC;">&quot;[object Array]&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  $ERROR<span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/* ... */</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>It is, of course, very hard to avoid these false positives. <strong>We can only guess which things are more likely to be compliant</strong>. We can also ignore these errors: if certain environment fails one test due to non-conformance of unrelated component, that component should simply be fixed as well.</p>
<p>Test suite has some minor inconsistencies — missing semicolons here and there, or extra ones (after statements). There are superfluous <code>!(... == ...)</code> used instead of <code>(... != ...)</code>, as well as <code>if (... == true)</code> instead of <code>if (...)</code>. I also noticed <a href="http://code.google.com/p/sputniktests/issues/detail?id=13">few</a> <a href="http://code.google.com/p/sputniktests/issues/detail?id=12">missing</a> <a href="http://code.google.com/p/sputniktests/issues/detail?id=14">conformance</a> checks.</p>
<p>I have no doubt all these annoyances will be gone in the future.</p>
<h2 id="future-work">Future work</h2>
<p>Having extensive compliance test suite can really <strong>help modern browsers achieve even better conformance</strong>. I hope we&#8217;ll see some of the bugs revealed through the Sputniktests fixed in the near future. I hope we&#8217;ll also see less regressions, if browser implementors integrate it into existing test suites. I also hope Sputniktests can help people learn and understand ECMAScript better.</p>
<p><a href="https://github.com/kangax/sputniktests-webrunner">Web runner is published on github</a>, so that anyone can contribute easily. There are many more things we can improve. I can think of additional features like <strong>running separate sections of tests</strong> or even individual ones; being able to <strong>see test contents</strong> right in a browser, or make it possible to <strong>pause/resume test suite execution</strong>.</p>
<p>Any comments, corrections, suggestions are as always very much welcomed.</p>
<p>And finally, I would like to, once again, thank Sputniktest team for their outstanding efforts to help move web forward.</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%2Fsputniktests-web-runner%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fperfectionkills.com%2Fsputniktests-web-runner%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/sputniktests-web-runner/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Professional Javascript. Review.</title>
		<link>http://perfectionkills.com/professional-javascript-review/</link>
		<comments>http://perfectionkills.com/professional-javascript-review/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 00:16:54 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[review]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/professional-javascript-review/</guid>
		<description><![CDATA[
  .professional-javascript h2 { margin-bottom: 1em; }
  .professional-javascript ul li { margin-bottom: 0.5em; }



    
Few months ago, I promised Nicholas Zakas to review 2nd edition of his &#8220;Professional Javascript for Web Developers&#8221; (published by Wrox). Nicholas was kind enough to send me a copy of a book, but the lack [...]]]></description>
			<content:encoded><![CDATA[<style type="text/css">
  .professional-javascript h2 { margin-bottom: 1em; }
  .professional-javascript ul li { margin-bottom: 0.5em; }
</style>
<div class="professional-javascript">
<p>
    <img src="http://ecx.images-amazon.com/images/I/41RJ3DptkQL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU01_.jpg" style="float: right;"></p>
<p>Few months ago, I promised <a href="http://www.nczonline.net/">Nicholas Zakas</a> to review 2nd edition of his <a href="http://www.amazon.com/Professional-JavaScript-Developers-Wrox-Guides/dp/0764579088" title="Professional Javascript on amazon">&#8220;Professional Javascript for Web Developers&#8221; (published by Wrox)</a>. Nicholas was kind enough to send me a copy of a book, but the lack of time at that moment didn&#8217;t let me dive into reviewing it right away. Last week I have decided to finally get together and fulfill a long-standing promise.</p>
<p>Here it goes:</p>
<h2 id="what_i_liked">What I liked</h2>
<ul>
<li>Technically correct most of the time (many other books, for example, have much more errors and misconceptions).</li>
<li>Follows specs and standards closely, uses proper terminology.</li>
<li>Covers great variety of topics.</li>
<li>Promotes good practices, both — javascript and general programming ones.</li>
</ul>
<h2 id="what_i_didn8217t_like">What I didn&#8217;t like</h2>
<ul>
<li>Often oversimplified. Covers only about 85% of core language.</li>
<li>Browsers behavior and bugs are often talked about without specifying actual versions (*)</li>
<li>Uses unnecessary browser sniffing.</li>
<li>Information about ECMAScript 5 is heavily outdated.</li>
</ul>
<p>(*) Because of this, some statements turn out to be plain wrong. For example, there is — <em>&#8220;When defining an object via object literal notation, the Object constructor is never actually called (except in Firefox).&#8221;</em>. Yet, this only happens in earlier versions of Firefox (&lt;= 2, IIRC). Then there&#8217;s — <em>&#8220;The children collection is supported in all browsers except Firefox.&#8221;</em> — however, Firefox 3.5 does in fact have working <code>children</code>. Unfortunately, there are few more of such misleading assertions.</p>
<h2 id="general_nitpicks">General nitpicks</h2>
<ul>
<li>Not all examples work in Safari 2.x (although book claims they do)</li>
<li>Many methods are not written defensively (e.g. assuming that certain methods/properties exist before accessing them)</li>
<li>Use of <code>new Array()</code> instead of <code>[]</code> (probably for clarity)</li>
<li>Mix of HTML and XHTML (ideally, it would be nice to drop XHTML for <a href="http://hixie.ch/advocacy/xhtml" title="Sending XHTML as text/html Considered Harmful ">well known reasons</a>)</li>
<li>Variables are sometimes initialized with (redundant) <code>null</code></li>
</ul>
<h2 id="verdict">Verdict</h2>
<p>The book is a solid foundation for anyone serious about Javascript. Even though not perfect, it is probably one of the best ones on the market at the moment; The quality of so many other books is simply horrendous. I wish &#8220;Professional Javascript&#8221; would cover things in more details and employed defensive techniques, or even better — had defensive mindset. However, the fact that it doesn&#8217;t only leaves room for future improvement. I would rate it as <strong>7/10</strong>.</p>
<p>If anyone is interested in more detailed <del>ramblings</del> review, here it is — all broken down by chapters. Enjoy.</p>
<h2 id="chapter_2">Chapter 2</h2>
<p>Chapter 2 is about <strong>Javascript in HTML</strong>. It covers script and noscript elements, document modes and the way scripts are embedded into web pages. It&#8217;s nice to see good practices being promoted here: not using html comments in scripts, preferring external scripts to inline ones as well as script elements positioning in the document for best performance. One glaring mistake in this chapter is mention of &#8220;&lt;/script>&#8221; terminating script element, and how &#8220;&lt;/scr&#8221; + &#8220;ipt>&#8221;  should be used instead. This is not really true. What <a href="http://www.w3.org/TR/REC-html40/types.html#type-cdata">terminates script element in HTML4.01</a> is actually &#8220;&lt;/&#8221;; and to work around it, it&#8217;s usually recommended to break tags as &#8220;&lt;&#8221; + &#8220;/script>&#8221; or &#8220;&lt;\/script>&#8221;. </p>
<p>When explaining CDATA markers, I wish author mentioned that it is mime-type that affects document nature. Prepending document with XHTML doctype — contrary to a popular myth — doesn&#8217;t make document true XHTML. Serving it with application/xhtml+xml does. This is important because CDATA markers are now being blindly injected all over the web into documents served as HTML (but with XHTML doctype).</p>
<h2 id="chapter_3">Chapter 3</h2>
<p>Chapter 3 gives a brief, yet in-depth overview of <strong>language basics</strong>. It&#8217;s a pretty friendly introductory chapter. At times, it feels like a couple more things could be added to explanations. Section on number conversion, for example, mentions <code>Number</code> and <code>parseInt</code> but misses unary plus (<code>+</code>) operator. Same goes for string conversion — so commonly used <code>something + ''</code> solution is missing. </p>
<p>Some things in this chapter sound questionable. For example, it was strange to hear that <em>&#8220;Logically, a null value is an empty object pointer&#8221;</em>, that <em>&#8220;The value undefined is a derivative of null&#8221;</em> and that <em><code>var o = new Object; //legal, but not recommended</code></em>. I also didn&#8217;t agree with the assertion that <em>&#8221;[&#8230;] ECMAScript’s data types have dynamic aspects that make other data types unnecessary&#8221;</em> — proper hash table would certainly be a useful addition to a language (since prototypal nature of objects in ECMAScript makes it a rather non-trivial task). There&#8217;s an insignificant mistake about undeclared variable — <em>&#8220;Only one operation can be performed on an undeclared variable: you can call typeof on it.&#8221;</em> — is not technically true; <code>delete</code> operator will not throw <code>ReferenceError</code> either when given undeclared identifier.</p>
<p>Another thing I wish author gave more attention to is the notion of native vs. host objects. Instead, there&#8217;s only a very brief section about IE host objects — <em>&#8220;The Internet Explorer (IE) implementation of JavaScript has a slightly different approach to JavaScript objects. In IE, only developer-defined objects inherit from Object. All Browser Object Model (BOM) and Document Object Model (DOM) objects are represented differently and so may not have all of the properties and methods of Object.&#8221;</em> Unfortunately, IE is not the only browser whose environment has &#8220;misbehaving&#8221; host objects. It would be nice to see proper explanation of true nature of host objects and caution about how unpredictable they really are (and, more importantly, <strong>are allowed to be</strong>, by specification).</p>
<h2 id="chapter_4">Chapter 4</h2>
<p>Chapter 4 presents simple and clear explanation of variables, as well as so-often-crucial difference between objects and primitives. It&#8217;s nice to see argument passing (a source of so many confusions) explained correctly and thoroughly. Another pleasant surprise is Activation/Variable objects being referenced by their original names (contrary to what so many other authors like to do). Undeclared assignments are recommended against, however there&#8217;s no mention of related IE bugs, nor is there an explanation of the difference between variable declaration in global context and undeclared assignments (which might not be very important, after all). Explanation of garbage collection is a nice ending of the chapter.</p>
<p>On the down side, some things are only touched upon briefly and some are plain incorrect.</p>
<p>Note on <code>typeof</code> operator is overly generic and misleading — <em>&#8221;[&#8230;] When used on a regular expression, typeof incorrectly returns “function” as well.&#8221;</em> <code>typeof</code> does in fact return &#8220;function&#8221; for regex objects but only in <strong>some environments</strong> — definitely not everywhere. The reason this happens is because in those environments regex objects actually implement internal [[Call]] method. By specification, native objects implementing [[Call]] should return &#8220;function&#8221; when applied <code>typeof</code> to, so implementations that do this are actually very much conforming.</p>
<p>Another incorrect statement is — <em>&#8220;Even though there are only two types of execution contexts [&#8230;]&#8221;</em>. Third overlooked type of execution context is, of course, eval one. Since eval context is not mentioned, its semantics are not mentioned either (however, eval code is being discussed later when talking about global <code>eval</code> method).</p>
<p>Finally, author talks about scope augmentation and how both <code>with</code> and <code>catch</code> affect execution context — <em>&#8220;Certain statements cause a temporary addition to the front of the scope chain that is later removed after code execution. There are two times when this occurs [&#8230;]&#8221;</em>. What&#8217;s unfortunately missing here is mention of named function expressions which result in scope augmentation as well. That is a third — perfectly valid — scenario of scope augmentation.</p>
<h2 id="chapter_5">Chapter 5</h2>
<p>Chapter 5 is about <strong>reference types — Object, Array, Date, RegExp, etc</strong>. As always, each type is discussed in great detail and with plenty of corresponding examples. It&#8217;s an excellent overview of these language types. The chapter also emphasizes what to avoid, such as trailing commas after last value in array and object literals. However, there are few ambiguous statements and, as with other parts of the book, some things seem to be a bit oversimplified.</p>
<p>As an example, author says — <em>&#8220;There are two ways to create an instance of Object&#8221;</em>. What goes unnoticed is that those are <strong>two explicit ways</strong> to create an object, and that there&#8217;s also an implicit one via function contsructor, e.g.: <code>new (function(){ this.foo = 'bar'; });</code>.</p>
<p>A slight ambiguity is encountered when talking about object literals — <em>&#8220;In this example, the left curly brace ({) signifies the beginning of an object literal because it occurs after an assignment operator (in any other context, the left curly brace indicates the beginning of a block statement).&#8221;</em> This phrase can be understood as if braces constitute object literal only when it is on the right hand side of assignment expression (as in this case). It would be better if instead author mentioned that braces constitute object literal <strong>when in expression context</strong> (and block — when in statement context); few examples of expression and statement contexts would be helpful too.</p>
<p>There&#8217;s no mention of number literals being valid production in property names of object literals (i.e. — { 5: &#8216;foo&#8217; }); It was surprising not to see the discussion of dot property access vs bracket-based one (&#8220;[&#8221; and &#8220;]&#8221;) — something that I find to be rather important. One notable difference, of course, is that with bracket accessor it is possible to access properties whose names are not valid identifiers, such as &#8220;class&#8221; or &#8220;foo-bar&#8221;. When discussing arrays and their methods, it would be nice to see a mention of Array#sort not guaranteed to be stable.</p>
<p>I found section on function expressions vs. function declarations to be very short and simplistic. Although author rightfully describes difference between two in terms of when functions are instantiated (declaration — during variable declaration phase, expression — during actual execution), there are <a href="http://yura.thinkweb2.com/named-function-expressions/">many interesting things that are left untouched</a>: named function expressions and their semantics, use of function declarations in statements and how it should be avoided, infamous NFE bugs in JScript and why naming functions could be beneficial for profiling and debugging. Finally, there&#8217;s a rather vague and overgeneralized statement about Safari not understanding named function expressions.</p>
<p>I didn&#8217;t like that <code>this</code> value was being called scope, as scope can be misinterpreted with what&#8217;s otherwise known as execution context. I would rather see <code>this</code> being called simply as &#8220;this value&#8221;. </p>
<p>Unfortunately, there was also no mention of JScript bugs with <code>Number.protoype.toFixed</code> and <code>String.prototype.split</code> with regex and capturing groups.</p>
<p>Another misleading assertion was — <em>&#8220;Though ECMA-262 doesn’t indicate a way to access the Global object directly [&#8230;]&#8221;</em>. It&#8217;s not clear why Mr. Zakas didn&#8217;t provide and explain rather ubiquitous way of accessing Global object from within any context — <code>(function(){ return this; })();</code> — especially crucial in non-browser environments, which might not have global <code>window</code> property.</p>
<h2 id="chapter_6">Chapter 6</h2>
<p>Chapter 6 describes <strong>OOP in Javascript</strong>. It was nice to see author talk about constructors rather than classes, compare various ways of creating reusable objects and explain popular conventions, such as capitalizing constructors. I was a bit disappointed to hear a somewhat vague — <em>&#8221;[&#8230;] the this object always points to the Global object (window in web browsers) when a function is called in the global scope.&#8221;</em>. Even though technically correct, in my opinion, it would be better to say that function&#8217;s <code>this</code> value references Global object <strong>when function is called as a function</strong>, no matter from which scope — global or local.</p>
<p>The rest of the chapter delves into OOP in great detail, and is sprinkled generously with very helpful and descriptive diagrams. Speaking of prototypal inheritance, Zakas attributes a popular pattern of cloning to Douglas Crockford who wrote an article on this object in 2006. However, I&#8217;m not sure why there&#8217;s no attribution to Lasse Reichstein Nielsen who <a href="http://groups.google.com/group/comp.lang.javascript/msg/5d06e72e55d5bf11">presented it</a> 3 years earlier than Crockford, in 2003.</p>
<h2 id="chapter_7">Chapter 7</h2>
<p>Chapter 7 is about more complex aspects of ECMAScript — <strong>anonymous functions, recursion, closures, private variables</strong> and other related goodness. </p>
<p>Unfortunately, it starts somewhat badly by making few erroneous statements about function expressions. First, it says that <em>&#8220;function expressions create anonymous functions&#8221;</em> (not necessarily). Then it asserts that <code>function(arg0, arg1, arg2){ }</code> is a valid code (not always; it is <a href="http://yura.thinkweb2.com/named-function-expressions/#expr-vs-decl">only &#8220;valid&#8221; in expression context</a> — such as in assignment or return statements; when in Global code or in function body, this is, of course, a SyntaxError). </p>
<p>Nevertheless, chapter goes on to explain closures quite thoroughly, paying attention to all of the details of how Activation objects are created and initialized, how they constitute scope chain and how this all relates to closures. A minor nitpick is that self-executing anonymous function in few examples are not wrapped with parenthesis; it would be nice if author mentioned <a href="http://peter.michaux.ca/articles/an-important-pair-of-parens">this &#8220;wrapping&#8221; as a good practice</a> and explained why not wrapping functions leads to confusion when scanning through large functions.</p>
<p>The rest of the chapter is informative and in-depth, but unfortunately presents yet another harmful example towards the end — when simulating private variables it <strong>uses undeclared assignment</strong> to define variable as global one and does so on purpose! This is especially bizarre, given that a bit earlier there&#8217;s a clear recommendation to avoid such &#8220;pattern&#8221;. Undeclared assignment could be easily avoided there, of course.</p>
<h2 id="chapter_8">Chapter 8</h2>
<p><strong>Browser Object Model</strong> is the topic of this chapter. It talks about window as well as its properties/methods, location, navigator and other &#8220;global&#8221; members provided by browsers. I have nothing but positive comments here. The only nitpick is with <code>getQueryStringArgs</code> abstraction, which suffers from object being used as a hash table (and have keys &#8220;conflict&#8221; with <code>Object.prototype.*</code> members).</p>
<h2 id="chapter_9">Chapter 9</h2>
<p>This chapter talks about <strong>client detection</strong>. Fortunately, author explains that capability/feature detection is a more robust approach to browser scripting. However, I feel that some things could be mentioned in more details and under a different angle. For example, there&#8217;s no recommendation to test standard methods before proprietary ones, when possible. Neither is there an explanation of <code>typeof</code> being <a href="http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting">more reliable way of testing host objects</a> presence and/or capabilities. A couple of feature test examples are both rather trivial; I was expecting to see more involved ones. There is however a rather entertaining coverage of userAgent string history and a comprehensive method of parsing that string. Overall, I wish there was more emphasis on the dangers and fragile nature of browser sniffing in this part of the book.</p>
<h2 id="chapter_10">Chapter 10</h2>
<p>Chapter 10 describes <strong>Document Object Model</strong> gradually and throughly. It focuses on properties and semantics of all Node types, and how to work with them. Relationships between nodes are presented very clearly through graphs. </p>
<p>I&#8217;m not a fan of <code>convertToArray</code> solution presented there, as it uses rather slow and unnecessary try-catch at run time instead of testing for IE quirk once. It&#8217;s also strange to hear rather bold statements such as — <em>&#8220;The Element type constructor and prototype are accessible in script in all browsers, including IE as of version 8.&#8221;</em> This is far from being true: at least Safari &lt;=2 and Opera &lt;8 don&#8217;t provide these &#8220;constructors&#8221;. It&#8217;s very possible that mobile browsers do not expose them either.</p>
<p>Quite shockingly, an example of <code>document.createElement</code> specifics in IE is presented with blatant and completely unnecessary browser sniff. It was ironic to see this &#8220;solution&#8221; after previous chapter discussed how feature detection should be preferred to browser sniffing whenever possible.</p>
<p>When talking about <code>children</code> there is no mention of bugs in older Safari. <code>contains</code> section, on the other hand, warns about Safari 2.x bugs, but spoils the moment by suggesting to sniff for browser (something that&#8217;s, again, <a href="http://yura.thinkweb2.com/cft#ELEMENT_CHILDREN_RETURNS_ELEMENT_NODES">unnecessary</a>). An implementation of <code>contains</code> that follows unfortunately turns sniffing advise into reality.</p>
<p>An implementation of <code>getInnerText</code> fortunately tests for features, but fails to mention <a href="http://stackoverflow.com/questions/1359469/innertext-works-in-ie-but-not-in-firefox/1359822#1359822">differences</a> between <code>textContent</code> and <code>innerText</code>.</p>
<p>Implementations of <code>loadScriptString</code> and <code>loadStyleString</code> that follow are excellent examples of proper abstractions, where features are tested and are tested in correct order (however, it would be nice to see alternative example which would avoid run-time try-catch in favor of single load-time test).</p>
<h2 id="chapter_11">Chapter 11</h2>
<p>This covers <strong>DOM Level 2 and 3</strong>; Styles, Traversal and Range modules. Everything presented here is informative and thought-through. Minor nitpick is vague statements about browser bugs and corresponding browser versions. There&#8217;s also a warning about <code>float</code> &#8212; <code>cssFloat</code> mapping, but nothing about <code>for</code> &#8212; <code>htmlFor</code> one. </p>
<p>I liked that most of cross-browser abstractions use feature detection in correct order. One notable example is <code>getBoundingClientRect</code> abstraction which actually shows non-trivial feature test for the first time. The only downside to that solution is that it uses (often slow-to-create) <code>arguments.callee</code> instead of a special variable in a closure — to store temporary <code>offset</code> value.</p>
<p>Chapter ends with a comprehensive overview of Ranges — both DOM and proprietary IE ones.</p>
<h2 id="chapter_12">Chapter 12</h2>
<p>This one talks about <strong>Events</strong>. Capturing, bubbling phases and event flow are illustrated nicely with diagrams. There are sections on DOM Level 0 and Level 2 event handlers, discussing both — DOM and IE event models. Other topics include event object, simulating events and memory considerations. </p>
<p>Unfortunately, scope chain <a href="http://www.jibbering.com/faq/names/event_handler.html">augmentation of intrinsic event handlers</a> is not mentioned. Event abstraction utility is rather simple. When describing events order for dblclick, there&#8217;s no mention of IE deviations; instead, these events are claimed to be fired in exact order (presented there) — something that&#8217;s <a href="http://unixpapa.com/js/mouse.html">rather misleading</a>. Nothing is being said about Opera lack of contextmenu event and when talking about event delegation, there&#8217;s no mention of focus/blur events.</p>
<p>It was very nice to see &#8220;beforeshow&#8221; / &#8220;beforehide&#8221; events discussed, together with effect of &#8220;unload&#8221; event handler on page caching. Event model specifics of less traditional devices/clients, such as Wii and iPhone, were touched upon as well.</p>
<p>&#8220;Removing event handlers&#8221; section is a little disappointing. It makes it sound as if Internet Explorer always leaks memory as pages are navigated, suggesting &#8220;unload&#8221; event as a remedy. Instead, it would be useful to see <strong>actual leak pattern</strong>, and explanation of <a href="http://www.jibbering.com/faq/faq_notes/closures.html#clMem">event handlers forming circular references</a> through closures. It would also make sense to mention that attaching event handlers &#8220;properly&#8221; allows to avoid both — unload cleanup (and so disabled bfcache) and leaks.</p>
<h2 id="chapter_13">Chapter 13</h2>
<p><strong>Scripting forms</strong> is about&#8230; forms, and everything related: from basic things like submitting them to more advanced like rich text editing and serialization. As always, there&#8217;s plenty of good recommendations, suggesting to avoid things like form resetting, accessing forms directly on a <code>document</code>, accessing form controls directly on forms, etc. </p>
<p>One rather important aspect I found missing here is the problem of <a href="http://www.jibbering.com/faq/names/index.html">unsafe names in forms</a>. Another insignificant nitpick is that  <code>getSelectedText</code> abstraction doesn&#8217;t feature test <code>selectionStart</code> on form control, before accessing it (it&#8217;s missing in Safari 2.0, for example). On a similar note, an example demonstrating tab forwarding is accessing a text field that might not exist. </p>
<p>This chapter presents a pretty solid function for form serialization, but it&#8217;s unfortunately a bit off and incorrectly serializes controls without names.</p>
<h2 id="chapter_14">Chapter 14</h2>
<p>This chapter dives into <strong>error handling in Javascript</strong>, as well as everything that has to do with debugging, including overview of debugging tools on various browsers. It&#8217;s an in-depth look at a great variety of error-handling aspects of cross-browser scripting.</p>
<p>Unfortunately, when talking about try-catch, author doesn&#8217;t mention rather important <a href="http://webbugtrack.blogspot.com/2007/11/bug-184-catch-to-try-catch-finally-in.html">IE deviations</a>. When describing <code>EvalError</code>, he doesn&#8217;t explain in which cases it might actually occur — something that specification makes very clear — <em>&#8220;if value of the eval property is used in any way other than a direct call (that is, other than by the explicit use of its name as an Identifier which is the MemberExpression  in a CallExpression), or if the eval property is assigned to, an EvalError exception may be thrown.&#8221;</em>. In fact, <code>EvalError</code> can be easily observed in, say, Firefox 3.5 where using <code>eval</code> in a new expression — <code>new eval()</code> — leads to exactly this type of exception.</p>
<p>Another potential source of confusion is with checking value for Array type in one of the examples. It&#8217;s being done via <code>instanceof</code> operator and without explanation of <a href="http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/">why it might not work</a> and what to do instead (note that iframe issue is mentioned later, in Chapter 20, however [[Class]]-based testing is not mentioned even there).</p>
<h2 id="chapter_15_16">Chapters 15 &amp; 16</h2>
<p>— are about <strong>XML in Javascript</strong>. One discusses XML DOM, XPath and XSLT support in browsers. The other one continues on the similar subject, delving into <strong>ECMAScript for XML (E4X)</strong>. Unfortunately, I&#8217;m not very familiar with these aspects of browser scripting, so can&#8217;t provide any useful feedback here. Overall, this section of a book looks like a solid foundation for anyone willing to master XML in Javascript.</p>
<h2 id="chapter_17">Chapter 17</h2>
<p>— is about <strong>Ajax</strong>. It talks about XHR objects, Cross-Domain requests, JSON, and Security — explaining each of those from the ground up. It was nice to see non-standard extensions mentioned — XHR&#8217;s <code>timeout</code> and &#8216;progress&#8217; events, Microsoft&#8217;s <code>XDomainRequest</code>, etc. One minor thing I didn&#8217;t like is that <code>createXHR</code> abstraction used (often expensive) <code>arguments.callee</code> instead of storing variable in a closure.</p>
<p>A slightly confusing explanation is given in <code>eval</code> section where phrases such as <em>&#8220;evaluate as data format&#8221;</em>, <em>&#8220;statement without name&#8221;</em>, and <em>&#8220;it identifies a value rather than a statement&#8221;</em> don&#8217;t make much sense; It looks like by &#8220;named statement&#8221; author really meant &#8220;labeled statement&#8221;, and by &#8220;identifies as a value&#8221; — &#8220;parsed as expression&#8221;.</p>
<h2 id="chapter_18">Chapter 18</h2>
<p>— is named <strong>&#8220;Advanced Techniques&#8221;</strong> and covers quite few interesting topics — scope-safe constructors, lazy function loading, binding and currying. It also explains timers quite extensively. </p>
<p>Strangely, a pattern of forking function declarations is not covered when talking about lazy-loading functions. That pattern is tremendously useful and is somewhat ubiquitous by now; I&#8217;m surprised it&#8217;s missing here. <code>bind</code> and <code>curry</code> abstractions are very simple (unoptimized), apparently only demonstrating general ideas behind them.</p>
<p>It would be nice to see more robust event abstraction: with error handling, so that integrity of event handlers is not compromised when one of them errors out. Drag and drop example is presented in a nice encapsulated way &#8211; using module pattern, however there is a slight mistake of using <code>indexOf</code> to check if element has certain class.</p>
<h2 id="chapter_19">Chapter 19</h2>
<p>— explains everything related to <strong>Client-Side storage</strong>: cookies, best practices on using them and some of the restrictions. A pretty solid cookie utility is presented there as well. Other things discussed are Internet Explorer user data and DOM Storage. </p>
<p>Unfortunately, it also describes <code>StorageItem</code> interface, which doesn&#8217;t exist in Web Storage specs any longer. Some of the <code>localStorage</code> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=510234">bugs</a> and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=509241">quirks</a> are not mentioned (quite obviously, since they didn&#8217;t even exist at the time of the writing). There&#8217;s no recommendation to prefer <code>getItem</code>/<code>setItem</code> to plain property accessors, since latter ones are rather destructive and are not generally safe. Compare:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  localStorage<span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'clear'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'foo'</span><span style="color: #339933;">;</span>
  localStorage.<span style="color: #660066;">clear</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 'foo', not a `clear` method</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// vs.</span>
  localStorage.<span style="color: #660066;">setItem</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'clear'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  localStorage.<span style="color: #660066;">getItem</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'clear'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 'foo'</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// the following is currently true in Firefox, but not WebKit (see: https://bugs.webkit.org/show_bug.cgi?id=30996)</span>
  localStorage.<span style="color: #660066;">clear</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// `clear` method</span></pre></div></div>

<h2 id="chapter_20">Chapter 20</h2>
<p>— is about <strong>Best Practices</strong>. I almost fully agree with everything said here. The chapter is full of valuable advice, both — Javascript and general ones. Not only does it tell you what to do, but also explains why. This is important.</p>
<p>There were moments when I didn&#8217;t share same vision as Mr. Zakas, such as the one where he recommends to use comments in places where there are large amounts of code; I believe in a different approach — breaking code into smaller, more understandable chunks, rather than adding comments on top. Another oddity was with example demonstrating decoupling of application logic and event handlers. Ironically, <code>validateValue</code> would both — validate and perform destructive action, changing visibility of an element. This was very unintuitive and is something I would avoid.</p>
<p>When talking about performance, it wasn&#8217;t clear why variable access is considered to take O(1) operations, and property lookup — O(N). Both of these have to go through some jumps and hops internally — variable is resolved via scope chain, whereas property — via prototype chain (and only if not found directly on an object). It&#8217;s understandable that property lookups are slightly slower, since besides actual property lookup, there&#8217;s also an initial &#8220;base&#8221; variable resolution, but where O(1) and O(N) are coming from was a mystery.</p>
<h2 id="chapter_21">Chapter 21</h2>
<p>This chapter talks about <strong>Upcoming APIs</strong>, namely Selectors API and those from HTML5. Describing specifications that are in a state of draft is a risky business, which author rightfully mentions upfront. This section of a book is a nice cursory overview of most of the upcoming goodness — <code>querySelectorAll</code>, <code>getElementsByClassName</code>, <code>classList</code>, data attributes, cross-document messaging, media elements, canvas, offline support, history management, and others.</p>
<h2 id="chapter_22">Chapter 22</h2>
<p>The finale of the book is <strong>The Evolution of JavaScript</strong>. It first covers wide range of extensions to JavaScript, from 1.5 to 1.8 — constants, accessors, array extras, array and string generics, block-level scope with <code>let</code>, generators and iterators, as well as few others. The only minor nit here is that  examples of array extras had functions with unused parameters. </p>
<p>Unfortunately, a lot of information about ECMAScript 5 here is outdated. It&#8217;s even called by its previous name — ECMAScript 3.1.</p>
<ul>
<li>[[Flexible]] attribute used throughout the examples is now called [[Configurable]]</li>
<li>[[Getter]] and [[Setter]] attributes are called [[Get]] and [[Set]] accordingly</li>
<li>[[Const]] attribute no longer exists</li>
<li><code>Object.clone</code> no longer exists</li>
<li><code>Object.keys</code> doesn&#8217;t accept second (sort) argument</li>
<li>Function objects don&#8217;t have <code>name</code> or <code>parameters</code> properties</li>
<li><code>arguments</code> object is not an instance of <code>Array</code></li>
<li>Decimals do not exist</li>
<li>“use subset cautious”; doesn&#8217;t exist and is replaced with Use Strict Directive — &#8220;use strict&#8221;;</li>
</ul>
<p>There&#8217;s also a slight mistake in one of the examples when accessing <code>getPrototypeOf</code> as an instance method, rather than as static one of an <code>Object</code>.</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%2Fprofessional-javascript-review%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fperfectionkills.com%2Fprofessional-javascript-review%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/professional-javascript-review/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Whitespace deviations</title>
		<link>http://perfectionkills.com/whitespace-deviations/</link>
		<comments>http://perfectionkills.com/whitespace-deviations/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 06:10:10 +0000</pubDate>
		<dc:creator>kangax</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://perfectionkills.com/whitespace-deviations/</guid>
		<description><![CDATA[I am reading a Regular Expression Cookbook by Jan Goyvaerts and Steven Levithan. It&#8217;s a truly excellent book on a subject, with an incredible level of attention to details. I am only half-way through the book, but have already learned few things about regular expressions &#8211; both general and javascript-related ones.
One thing I noticed missing [...]]]></description>
			<content:encoded><![CDATA[<p>I am reading a <a href="http://www.amazon.com/gp/product/0596520689">Regular Expression Cookbook</a> by Jan Goyvaerts and Steven Levithan. It&#8217;s a truly excellent book on a subject, with an incredible level of attention to details. I am only half-way through the book, but have already learned few things about regular expressions &#8211; both general and javascript-related ones.</p>
<p>One thing I noticed missing in the book was a mention of whitespace character class (<code>\s</code>) discrepancies in current ECMAScript implementations. Cookbook rightfully explains that <code>\s</code> in Javascript matches any character <strong>defined as whitespace by the Unicode standard</strong>. What it fails to mention is how horribly this rule is actually implemented in modern browsers. While most of the implementations correctly handle ASCII whitespace characters, such as &#8211; <code>U+0020</code> (Space), <code>U+000B</code> (Vertical Tab) and <code>U+000A</code> (Line Feed) &#8211;  there&#8217;s much more chaos in anything above <code>U+2000</code> (EN QUAD) point.</p>
<p>In practice such non-conformance can lead to surprising results when implementing something like <code>trim</code> function. If <code>trim</code> were to utilize <code>\s</code>, than it could miss quite common characters like <code>U+00A0</code> (No-Break Space); In fact, <code>trim</code> used in jQuery or Prototype uses exactly that &#8211; standard whitespace character class (<code>\s</code>) &#8211; and so fails with any of these troublesome characters. One of the solutions, of course, is to replace <code>\s</code> with a custom character class, e.g.: &#8211; <code>[\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029]</code></p>
<p>This topic comes up once in a while on comp.lang.javascript and there have been some efforts to <a href="http://www.merlyn.demon.co.uk/js-valid.htm#RsT">document these discrepancies</a>. I wanted to make a simple table of modern browsers compliance and used a test <a href="http://groups.google.com/group/comp.lang.javascript/msg/4bd0e6e742b83f91">provided once by Richard Cornford</a> (also <a href="http://yura.thinkweb2.com/rcornford_whitespace_test.html">available online </a> for anyone to try it out). </p>
<p>Here’s a table demonstrating above mentioned deviations. It’s good to see Safari 4+ and Chrome 2+ conforming to specs fully. Hopefully, upcoming versions of Firefox will also take care of the remaining &#8220;failures&#8221;.</p>
<style type="text/css">
  table { font-size: 12px; font-family: monospace; }
  th { font-weight: normal; }
  td.pass { background-color: green; color: #fff; text-align: center; }
  td.fail { background-color: red; color: #fff; text-align: center; }
</style>
<table style="margin-bottom: 1.5em;">
<thead>
<tr>
<th style="width:21em;">Code point / Browser</th>
<th>Firefox 2-3.5</th>
<th>Safari 2.0-3.2.1</th>
<th>Safari 4</th>
<th>Opera 9.25, 9.64</th>
<th>Opera 10</th>
<th style="width:4em;">IE 6-8</th>
<th>Chrome 2-3</th>
<th>Konqueror 4.2.2</th>
</tr>
</thead>
<tbody>
<tr>
<td>(0&#215;0009) [ASCII Tab]</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
</tr>
<tr>
<td>(0&#215;000A) [ASCII Line Feed]</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
</tr>
<tr>
<td>(0&#215;000B) [ASCII Vertical Tab]</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;000C) [ASCII Form Feed]</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
</tr>
<tr>
<td>(0&#215;000D) [ASCII Carriage Return]</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
</tr>
<tr>
<td>(0&#215;0020) SPACE</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
</tr>
<tr>
<td>(0&#215;00A0) NO-BREAK SPACE</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;1680) OGHAM SPACE MARK</td>
<td class="fail">FAIL</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;180E) MONGOLIAN VOWEL SEPARATOR</td>
<td class="fail">FAIL</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="fail">FAIL</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;2000) EN QUAD</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;2001) EM QUAD</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;2002) EN SPACE</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;2003) EM SPACE</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;2004) THREE-PER-EM SPACE</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;2005) FOUR-PER-EM SPACE</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;2006) SIX-PER-EM SPACE</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;2007) FIGURE SPACE</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;2008) PUNCTUATION SPACE</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;2009) THIN SPACE</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;200A) HAIR SPACE</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;2028) LINE SEPARATOR</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;2029) PARAGRAPH SEPARATOR</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;202F) NARROW NO-BREAK SPACE</td>
<td class="fail">FAIL</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;205F) MEDIUM MATHEMATICAL SPACE</td>
<td class="fail">FAIL</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="fail">FAIL</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
<tr>
<td>(0&#215;3000) IDEOGRAPHIC SPACE</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
<td class="pass">PASS</td>
<td class="fail">FAIL</td>
</tr>
</tbody>
</table>
<p>Tests for Firefox, Safari and Opera were performed on Mac OS X (10.5.8); IE and Chrome &#8211; on Windows XP Pro SP2 (via VMWare); and Konqueror &#8211; on Ubuntu 9.04 (via VMWare)</p>
<p><strong>Edit (28/09/2009)</strong></p>
<p>Clarified operating systems (and their versions) used for testing; Aligned characters in a table by code point; Updated Opera to 10RC, added Chrome 3 to results, combined FF columns into one, since they are the identical; Sorted table by code point. Thanks to Dr J R Stockton and Luke Smith for suggestions.</p>
<p><strong>Edit (04/09/2009)</strong></p>
<p>Updated Opera 10RC to Opera 10 (Thanks to Garrett Smith for test); tested and updated table with results of Safari 2.x and older 3.x versions; fixed a bug in a testcase where `char` identifier (one of future reserved words as per ES3) would prevent script parsing in Safari 2.x</p>
<div class="tweetmeme_button" style="float: right; margin-left: 30px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fperfectionkills.com%2Fwhitespace-deviations%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fperfectionkills.com%2Fwhitespace-deviations%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/whitespace-deviations/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>
