<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>NCZOnline</title>
	
	<link>http://www.nczonline.net/blog</link>
	<description>The Official Web Site of Nicholas C. Zakas</description>
	<pubDate>Wed, 17 Mar 2010 00:00:08 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.1</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/nczonline" /><feedburner:info uri="nczonline" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Empty-string URLs in HTML - A followup</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/sqz1HleFSHk/</link>
		<comments>http://www.nczonline.net/blog/2010/03/16/empty-string-urls-in-html-a-followup/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 13:00:09 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[HTML]]></category>

		<category><![CDATA[HTML5]]></category>

		<category><![CDATA[YSlow]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=2433</guid>
		<description><![CDATA[Late last year, after spending 10 days tracking down a horrific bug, I posted, Empty image src can destroy your site. The post laid out a problem present in almost all modern browsers regarding empty string URLs in HTML. Empty-string URLs look like this:
&#60;img src=""&#62;
&#60;script src=""&#62;
&#60;link rel="stylesheet" href=""&#62;
Depending on the browser, one or more of [...]]]></description>
			<content:encoded><![CDATA[<p>Late last year, after spending 10 days tracking down a horrific bug, I posted, <a href="http://www.nczonline.net/blog/2009/11/30/empty-image-src-can-destroy-your-site/">Empty image src can destroy your site</a>. The post laid out a problem present in almost all modern browsers regarding empty string URLs in HTML. Empty-string URLs look like this:</p>
<pre><code>&lt;img src=""&gt;
&lt;script src=""&gt;
&lt;link rel="stylesheet" href=""&gt;</code></pre>
<p>Depending on the browser, one or more of these elements will actually cause another request to the server. Not just any request, though, a request to the containing page. That means the entire markup of your page is regenerated and served even though no one is actually viewing it. The linked post explains in detail why this is problematic, but suffice to say, these type of unexpected requests to your server can bring down high-traffic sites by unexpected increasing traffic or alternately can corrupt user state information.</p>
<h2>Current state of browsers</h2>
<p>As a quick summary of where we are today, here&#8217;s how the various browsers stock up:</p>
<ul>
<li>Internet Explorer through version 8 make a request for <code>&lt;img src=""&gt;</code> only.</li>
<li>Firefox 3 and earlier makes a request for all three of the patterns.</li>
<li>Firefox 3.5 fixed the <code>&lt;img src="'&gt;</code> case but not the others.</li>
<li>Safari 4 makes a request for all three patterns.</li>
<li>Chrome 4 makes a request for all three patterns.</li>
<li>Opera doesn&#8217;t make a request in any of these instances.</li>
</ul>
<p>It&#8217;s not a pretty picture out there. But there has been movement since my last post.</p>
<h2>Forward progress</h2>
<p>Believing that this was the wrong behavior, I began contacting various browser vendors to ask if this behavior could be addressed. The most frequent response I received was that the browser was &#8220;following the standards&#8221; and shouldn&#8217;t be changed. I thought this was too dismissive and did some digging. The inconsistent treatment of empty-string URLs even within a single browser led me to believe that there was no specification governing this behavior. As it turned out, the specification to which everyone was referring was the URL specification (<a href="http://tools.ietf.org/html/rfc3986">RFC 3986 - Uniform Resource Identifiers</a>) and not HTML. While the URL specification does indicate that resolution for an empty string should result in the containing page, my argument was that this made no sense in the context of HTML.</p>
<h3>HTML5</h3>
<p>So in December, I posted a <a href="http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2009-December/024357.html">message</a> to the WHAT-WG mailing list to see if I could get some consensus on this issue. After a lengthy discussion and a bunch of research, everyone ended up agreeing that this behavior was unexpected and should be changed. This month, changes were made to HTML5 specifically stating that empty-string URLs should not cause server requests for the following (<a href="http://html5.org/tools/web-apps-tracker?from=4833&amp;to=4834">complete diff</a>):</p>
<pre><code>&lt;img src=""&gt;
&lt;input type="image" src=""&gt;
&lt;script src=""&gt;
&lt;link rel="stylesheet" href=""&gt;
&lt;embed src=""&gt;
&lt;object data=""&gt;
&lt;iframe src=""&gt;
&lt;video src=""&gt;
&lt;video poster=""&gt;
&lt;audio src=""&gt;
&lt;command icon=""&gt;
&lt;html manifest=""&gt;
&lt;source src=""&gt;</code></pre>
<p>Essentially, any tag that would result in the automatic download of an external resource will not make such a request if an empty-string URL is specified.</p>
<p>Thusfar, the Firefox team has agreed to make this update (see <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=531327">bug 531327</a>). I filed a bug with the Chromium team (<a href="http://code.google.com/p/chromium/issues/detail?id=38144">issue 38144</a>) and also commented on a bug that was already filed at WebKit (<a href="https://bugs.webkit.org/show_bug.cgi?id=30303">bug 30303</a>) and am waiting for updates (if a WebKit contributor would like to take this on, please do). Perhaps not surprisingly, I&#8217;ve had a little trouble pleading my case to Microsoft. I&#8217;ve not given up, but if you are or have a Microsoft contact that could help resolve this issue, please let me know.</p>
<h3>YSlow</h3>
<p>Since the empty-string URL issue really affects server performance, I asked the <a href="http://developer.yahoo.com/yslow/">YSlow</a> team if they could add in empty-string URL detection. Even though the issue with empty image URLs has been resolved in Firefox, it&#8217;s still present in other browsers, so YSlow&#8217;s flagging of this serious issue can help you avoid problems in other browsers.</p>
<p>In this initial release with the feature, there is a new non-default rule that you can turn on in a custom ruleset. To do so, click the Edit button next to the list of rulesets, check the box next to &#8220;Avoid empty src or href&#8221;. Click &#8220;Save ruleset as&#8230;&#8221; and type in a new name. Then, select your new ruleset from the dropdown box and click the &#8220;Run Test&#8221; button.</p>
<p style="text-align: center;"><img class="aligncenter" src="http://i764.photobucket.com/albums/xx289/nzakas/blog/yslow_emptysrc.png" alt="New YSlow rule for empty href or src" width="600" height="261" /></p>
<p>This new rule is under the &#8220;Server&#8221; group of rules. YSlow will correctly detect <code>&lt;img src=""&gt;</code> and <code>&lt;link rel="stylesheet" href=""&gt;</code> and give you an F if there are any instances of either of these patterns.</p>
<p style="text-align: center;"><img class="aligncenter" src="http://i764.photobucket.com/albums/xx289/nzakas/blog/yslow_femptysrc.png" alt="New YSlow rule for empty href or src" width="600" height="188" /></p>
<p>Note that due to a bug in YSlow, you&#8217;ll sometimes also get an A for this rule even if you do have one of the offending patterns present. This will be addressed soon.</p>
<h2>Thanks</h2>
<p>Things sometimes seem to move slowly on the Internet, but ultimately I believe things tend to get done correctly. We&#8217;re still likely at least a year away from never needing to worry about this issue again, and for that I need to thank a bunch of people:</p>
<ul>
<li>Jonas Sicking of Mozilla for suggesting that this issue be brought up on the WHAT-WG mailing list and for participating in the discussion.</li>
<li>Simon Pieters of Opera and Maciej Stachowiak  of WebKit for chiming in and agreeing that this behavior seemed broken.</li>
<li>Ian Hickson for making the adjustments in HTML5 so that this issue can be put to rest.</li>
<li>Stoyan Stefanov and the YSlow team for adding empty-string URL detection to YSlow.</li>
</ul>
<h2>Related posts</h2>
<ul class="related_post">
<li><a href="http://www.nczonline.net/blog/2009/12/22/protect-ie-from-empty-img-src/" title="Protect IE from empty img src">Protect IE from empty img src</a></li>
<li><a href="http://www.nczonline.net/blog/2009/11/30/empty-image-src-can-destroy-your-site/" title="Empty image src can destroy your site">Empty image src can destroy your site</a></li>
<li><a href="http://www.nczonline.net/blog/2005/09/01/web-architecture-2005/" title="Web Architecture: 2005">Web Architecture: 2005</a></li>
<li><a href="http://www.nczonline.net/blog/2009/09/24/moving-the-web-forward/" title="Moving the Web forward">Moving the Web forward</a></li>
<li><a href="http://www.nczonline.net/blog/2009/05/12/cookies-and-security/" title="Cookies and security">Cookies and security</a></li>
<li><a href="http://www.nczonline.net/blog/2009/05/05/http-cookies-explained/" title="HTTP cookies explained">HTTP cookies explained</a></li>
</ul>
<p>P.S. My new book, <a href="http://www.amazon.com/gp/product/059680279X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=059680279X">High Performance JavaScript</a> is coming out in early 2010. Need help now? Check out <a href="http://www.amazon.com/gp/product/047022780X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=047022780X">Professional JavaScript, 2nd Edition</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=sqz1HleFSHk:lB8v_DE9TnM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=sqz1HleFSHk:lB8v_DE9TnM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=sqz1HleFSHk:lB8v_DE9TnM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=sqz1HleFSHk:lB8v_DE9TnM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=sqz1HleFSHk:lB8v_DE9TnM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=sqz1HleFSHk:lB8v_DE9TnM:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/sqz1HleFSHk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2010/03/16/empty-string-urls-in-html-a-followup/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.nczonline.net/blog/2010/03/16/empty-string-urls-in-html-a-followup/</feedburner:origLink></item>
		<item>
		<title>Custom events in JavaScript</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/Oe0fKOWnDCY/</link>
		<comments>http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 13:00:53 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[BOM]]></category>

		<category><![CDATA[DOM]]></category>

		<category><![CDATA[Events]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=2429</guid>
		<description><![CDATA[Without a doubt, the most often-used paradigm in JavaScript is events. Events are a manifestation of the observer pattern, a well-defined computer science design pattern for loose coupling. Loose coupling is incredibly important for creating maintainable, stable codebases. I talk a lot about loose coupling and its importance in my talk, Scalable JavaScript Application Architecture [...]]]></description>
			<content:encoded><![CDATA[<p>Without a doubt, the most often-used paradigm in JavaScript is events. Events are a manifestation of the <a href="http://en.wikipedia.org/wiki/Observer_pattern">observer pattern</a>, a well-defined computer science design pattern for loose coupling. <a href="http://en.wikipedia.org/wiki/Loose_coupling">Loose coupling</a> is incredibly important for creating maintainable, stable codebases. I talk a lot about loose coupling and its importance in my talk, <a href="http://www.slideshare.net/nzakas/scalable-javascript-application-architecture">Scalable JavaScript Application Architecture</a> (<a href="http://developer.yahoo.com/yui/theater/video.php?v=zakas-architecture">video</a>), so I won&#8217;t talk too much about it here. However, the concept is very important to grasp if you wish to progress as a software engineer.</p>
<h2>Events</h2>
<p>Unless you&#8217;ve never written any JavaScript before, you&#8217;ve used events at some point in time (admittedly, if you&#8217;ve never written JavaScript before, the chances of your reading my blog are probably pretty slim). Put quite simply: the way that you tie behavior to web pages is through events. Events are a way of letting interested parties know that an important moment has occurred in the lifecycle of the application. For instance:</p>
<pre><code>window.onload = function(){
    Application.init();
};</code></pre>
<p>In this example, the <code>load</code> event is the interesting moment. I want to know when the window is fully loaded so that I can initialized the JavaScript application. The <code>onload</code> event handler is the location to where an event handler is assigned. The brilliant part is that <code>window</code> doesn&#8217;t care what web page is loaded or who is writing the code; it just knows that there&#8217;s a function to call when <code>load</code> occurs. This is the essence of loose coupling: when parts of an application have very limited knowledge of one another.</p>
<p>The <a href="http://javascript.about.com/od/browserobjectmodel/a/bom01.htm">Browser Object Model</a> (BOM) and <a href="http://www.w3.org/DOM/">Document Object Model</a> (DOM) publish events to allow developers access to the interesting moments of the browser and web page, respectively.</p>
<h2>Custom events</h2>
<p>It&#8217;s no surprise that most JavaScript libraries rely heavily on custom events since this is a pattern that web developers are familiar with. Every major JavaScript library provides its own events, components to enable easy custom event definition, or both. This makes sense, of course, since libraries want to be loosely-coupled to the execution environment, and therefore, to your code.</p>
<p>There&#8217;s nothing magic about custom events, though, and there&#8217;s no need to load an entire library if you&#8217;d like to experiment with custom events. An object that supports custom events needs to be able to do a small set of things:</p>
<ol>
<li>Assign an event handler for a particular event.</li>
<li>Remove an event handler for a particular event.</li>
<li>Fire an event and call all assigned event handlers.</li>
</ol>
<p>The following implements all of this basic functionality:</p>
<pre><code>//Copyright (c) 2010 Nicholas C. Zakas. All rights reserved.
//MIT License

function EventTarget(){
    this._listeners = {};
}

EventTarget.prototype = {

    constructor: EventTarget,

    addListener: function(type, listener){
        if (typeof this._listeners[type] == "undefined"){
            this._listeners[type] = [];
        }

        this._listeners[type].push(listener);
    },

    fire: function(event){
        if (typeof event == "string"){
            event = { type: event };
        }
        if (!event.target){
            event.target = this;
        }

        if (!event.type){  //falsy
            throw new Error("Event object missing 'type' property.");
        }

        if (this._listeners[event.type] instanceof Array){
            var listeners = this._listeners[event.type];
            for (var i=0, len=listeners.length; i &lt; len; i++){
                listeners[i].call(this, event);
            }
        }
    },

    removeListener: function(type, listener){
        if (this._listeners[type] instanceof Array){
            var listeners = this._listeners[type];
            for (var i=0, len=listeners.length; i &lt; len; i++){
                if (listeners[i] === listener){
                    listeners.splice(i, 1);
                    break;
                }
            }
        }
    }
};</code></pre>
<p>The <code>EventTarget</code> type has three methods: <code>addListener()</code>, <code>fire()</code>, and <code>removeListener</code>.</p>
<p>The <code>addListener()</code> uses the private <code>_listeners</code> object to store event handlers for various events. When an event handler is added, the method first checks to see if there&#8217;s a named property for that event type on the <code>_listeners</code> object, and if not, creates one containing an array. The event handler function is then saved to the array for later.</p>
<p>The <code>fire()</code> method fires an event with a given name. In effect, this method&#8217;s only job is to execute each event handler for the given event type. The method accepts either an object, in which case it&#8217;s expected to have a <code>type</code> property, or a string, in which case a new object is created and the string is assigned as the value of <code>type</code>. Next, if the event object doesn&#8217;t have a <code>target</code> property assigned, it is set to the current instance. This effectively creates an event object similar to the one most are familiar with via the BOM and DOM. Once the event object is created, the <code>_listeners</code> object is checked for event handlers, and if found, they are executed. Note that in order to mimic the BOM/DOM approach, event handlers are executed in the scope of <code>this</code> via the <code>call()</code> method.</p>
<p>The last method, <code>removeListener()</code>, simply reverses the process of <code>addListener()</code>. It searches through the <code>_listeners</code> property for the given event type to locate the specified event handler. If found, the event handler is removed by using the array&#8217;s <code>splice()</code> method, and otherwise it exits without doing anything.</p>
<p>Basic usage:</p>
<pre><code>var target = new EventTarget();
function handleEvent(event){
    alert(event.type);
};

target.addListener("foo", handleEvent);
target.fire({ type: "foo" });    //can also do target.fire("foo")
target.removeListener("foo", handleEvent);</code></pre>
<p>Practically speaking, you&#8217;ll likely not want to use an instance of <code>EventTarget</code> directly, but rather inherit from it:</p>
<pre><code>function MyObject(){
    EventTarget.call(this);
}

MyObject.prototype = new EventTarget();
MyObject.prototype.constructor = MyObject;
MyObject.prototype.foo = function(){
    this.fire("foo");
};

var o = new MyObject();

o.addListener("foo", function(){
    alert("Foo just happened.");
});

o.foo();</code></pre>
<p>Typically, events are fired in reaction to some other method call, as in this example (events are usually not fired external to the object that is publishing the events).</p>
<h2>What about&#8230;?</h2>
<p>This is a pretty barebones implementation of a custom event providing object, so inevitably someone will come along and ask why I didn&#8217;t include one feature or another. There are, of course, a lot of enhancements you can make to custom events if you so desire. Some enhancements others have implemented:</p>
<ul>
<li>Bubbling of events</li>
<li>Continue to execute event handlers even if one throws an error</li>
<li>Allow event handlers to cancel further processing or default actions</li>
</ul>
<p>Each of these can be built pretty easily on top of the base presented in this post.</p>
<h2>Conclusion</h2>
<p>Custom events are a very powerful and useful pattern in JavaScript programming, and your usage of them doesn&#8217;t have to rely on a large JavaScript library. Implementing your own custom events is easy. The implementation presented in this post is a minimum feature set that typically fulfills most requirements, but you can consider it as a starting point for more advanced functionality if your requirements are more complex.<br />
<h2>Related posts</h2>
<ul class="related_post">
<li><a href="http://www.nczonline.net/blog/2009/06/30/event-delegation-in-javascript/" title="Event delegation in JavaScript">Event delegation in JavaScript</a></li>
<li><a href="http://www.nczonline.net/blog/2007/02/06/event-order-of-blur-and-change/" title="Event order of blur and change">Event order of blur and change</a></li>
<li><a href="http://www.nczonline.net/blog/2009/09/29/web-definitions-dom-ajax-and-more/" title="Web definitions: DOM, Ajax, and more">Web definitions: DOM, Ajax, and more</a></li>
<li><a href="http://www.nczonline.net/blog/2009/03/24/xpath-in-javascript-part-2/" title="XPath in JavaScript, Part 2">XPath in JavaScript, Part 2</a></li>
<li><a href="http://www.nczonline.net/blog/2009/03/17/xpath-in-javascript-part-1/" title="XPath in JavaScript, Part 1">XPath in JavaScript, Part 1</a></li>
<li><a href="http://www.nczonline.net/blog/2009/02/03/speed-up-your-javascript-part-4/" title="Speed up your JavaScript, Part 4">Speed up your JavaScript, Part 4</a></li>
</ul>
<p>P.S. My new book, <a href="http://www.amazon.com/gp/product/059680279X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=059680279X">High Performance JavaScript</a> is coming out in early 2010. Need help now? Check out <a href="http://www.amazon.com/gp/product/047022780X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=047022780X">Professional JavaScript, 2nd Edition</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=Oe0fKOWnDCY:_jnHL475cig:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=Oe0fKOWnDCY:_jnHL475cig:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=Oe0fKOWnDCY:_jnHL475cig:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=Oe0fKOWnDCY:_jnHL475cig:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=Oe0fKOWnDCY:_jnHL475cig:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=Oe0fKOWnDCY:_jnHL475cig:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/Oe0fKOWnDCY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/</feedburner:origLink></item>
		<item>
		<title>Maintainable JavaScript: Don’t modify objects you don’t own</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/8Gd-HPtkAoU/</link>
		<comments>http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 13:00:07 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Maintainable]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=2422</guid>
		<description><![CDATA[The first talk I gave after arriving at Yahoo! was entitled Maintainable JavaScript (video). As with most topics I write or speak about, I didn&#8217;t think it would be terribly controversial. The basis of the talk is that hacking around on your own and writing code in an enterprise environment are two different things. Web [...]]]></description>
			<content:encoded><![CDATA[<p>The first talk I gave after arriving at Yahoo! was entitled <a href="http://www.slideshare.net/nzakas/maintainable-javascript-1071179">Maintainable JavaScript</a> (<a href="http://video.yahoo.com/video/play?vid=568351">video</a>). As with most topics I write or speak about, I didn&#8217;t think it would be terribly controversial. The basis of the talk is that hacking around on your own and writing code in an enterprise environment are two different things. Web developers are truly unique in that none of us learned what we know in school; we all began as hobbyists one way or another and taught ourselves most (if not all) of what we know.</p>
<h2>Professionalization</h2>
<p>The professionalization of web development has been a difficult journey because of our disparate beginnings. Even those who end up at large companies such as Yahoo! inevitably began on their own, hacking around. Perhaps you were even &#8220;the web guy&#8221; at a small company and could do pretty much whatever you wanted. When the large companies started tapping this previously undiscovered resource, it brought a lot of hackers into a corporate environment where they were met with constraints. No longer a lone soldier in a small battle, all of these self-taught, self-directed individuals had to figure out how to work together as a team.</p>
<p>At the time that I gave the talk (2007), web development was evolving into front-end engineering and people were having trouble with the transition. Smart folks like Nate Koechley talked about the <a href="http://www.slideshare.net/natekoechley/professional-frontend-engineering">professionalization of front-end engineering</a> (<a href="http://video.yahoo.com/watch/4671445/12486762">video</a>) and how our discipline was evolving. My talk was aimed at the same goal: helping front-end engineers adapt to JavaScript development in a team environment by making sure that their code was as maintainable as possible.</p>
<h2>Why can&#8217;t I modify objects I don&#8217;t own?</h2>
<p>I still gets email and comments about Maintainable JavaScript, and the most popular question is, &#8220;why can&#8217;t I modify objects I don&#8217;t own?&#8221; JavaScript is, of course, a dynamic language that allows you to add and remove objects and their members at any point in time. For many, this is precisely why they enjoy the language: there are very few constraints imposed by the language. And I was telling them not to do this. Why?</p>
<h3>Dependability</h3>
<p>The simple explanation is that an enterprise software product needs a consistent and dependable execution environment to be maintainable. In other languages, you consider already-existing objects as libraries for you to use in order to complete your task. In JavaScript, people saw already-existing objects as a playground in which you could do anything you wanted. My point was that you should treat the already-existing JavaScript objects as you would a library of utilities. Don&#8217;t override methods, don&#8217;t add new methods, don&#8217;t remove existing methods.</p>
<p>When you&#8217;re the only one working on a project, it&#8217;s easy to get away with these types of modifications because you know them and expect them. When working with a team on a large project, making changes like this cause mass confusion and a lot of lost time. I still remember a bug that occurred while working on <a href="http://my.yahoo.com">My Yahoo!</a> because someone had overridden <code>YAHOO.util.Event.stopEvent()</code> to do something else. It took days to track this problem down because we all assumed that this method was doing exactly what it always did. Once we discovered this, we also found other bugs because the same method was being used in other places with its original intended usage&#8230;but of course, it wasn&#8217;t behaving in that way. Unraveling this was an incredible mess and I&#8217;d be very happy if no engineers ever had to go through a similar exercise.</p>
<h3>Incompatible implementations</h3>
<p>But developer confusion isn&#8217;t the only problem. Another peril of modifying objects that you don&#8217;t own is the possibility of naming collisions and incompatible implementations. Take a lesson from the history of the <a href="http://prototypejs.org/">Prototype</a> JavaScript library. John Resig <a href="http://ejohn.org/blog/getelementsbyclassname-pre-prototype-16/">wrote about this</a> a while ago, so I&#8217;ll just quickly summarize. Prior to version 1.6, Prototype implemented its own <code>document.getElementsByClassName()</code> method long before it was part of HTML5 and long before any browser thought about implementing it natively. In addition, Prototype also added the <code>each()</code> method to <code>Array</code> objects. Thus, users of the Prototype library began writing code such as:</p>
<pre><code>document.getElementsByClassName("myclass").each(doSomething);</code></pre>
<p>This wasn&#8217;t a problem until the native <code>document.getElementsByClassName()</code> method was implemented. While Prototype&#8217;s version returned an instance of <code>Array</code>, the native implementation returns a <code>NodeList</code> object. Since <code>NodeList</code> doesn&#8217;t have an <code>each()</code> method, either natively or added by Prototype, the above coding pattern caused a JavaScript error when executed in browsers that had a native implementation of <code>document.getElementsByClassName()</code>. The end result is that users of Prototype had to upgrade both the library code and their own code; what a maintenance nightmare.</p>
<h2>What if everyone did it?</h2>
<p>Looking at a few isolated examples doesn&#8217;t really represent the enormity of the maintenance problem when you modify objects that you shouldn&#8217;t. To understand this point of view, it&#8217;s helpful to take a step back and look at <a href="http://en.wikipedia.org/wiki/Ethics">moral philosophy</a> (aka ethics). Moral philosophy is all about determining if an action is moral. There are many schools of thought on the topic, but I point towards a favorite modern philosopher, <a href="http://en.wikipedia.org/wiki/Immanuel_Kant">Immanuel Kant</a>.</p>
<p>While I don&#8217;t want to get too deeply into moral philosophy and open this up for philosophical debate, Kant was famous for trying to determine &#8220;universal law&#8221; as the basis for moral action. In short, you can determine if an act is moral by asking, what would happen if everyone did it? For example, what if everyone cheated on a test? In that case, the test becomes useless, so this must not be a moral action.</p>
<p>Applying this same line of reasoning to the topic at hand, what if everyone on your team started modifying objects that they didn&#8217;t own? What if I went in and made modifications to <code>document</code> and so did everyone else on my team? What if everyone on the team created their own global variables? I hope that it&#8217;s obvious just how detrimental these actions could be to a team development environment.</p>
<p>Simply put: if everyone on your team modified objects that they didn&#8217;t own, you&#8217;d quickly run into naming collisions, incompatible implementations, and maintenance nightmares.</p>
<p>As a side note, I find Kant&#8217;s question incredibly relevant to any system that must scale. &#8220;What if everyone did it?&#8221; can really save you some trouble when considered as part of a technical design.</p>
<h2>Conclusion</h2>
<p>Maintainable code is code that you don&#8217;t need to modify when the browser changes. You don&#8217;t know how browser developers will evolve existing browsers and the rate at which those evolutions will take place. The code you write needs to continue working in future browsers and with future versions of JavaScript libraries without modification, and you cannot ensure that when you&#8217;re modifying objects that you didn&#8217;t create in the first place. The only code you can be certain will remain the same is the code you write yourself.</p>
<p>I can&#8217;t state this strongly enough: your code is not maintainable when it requires modifications to objects you didn&#8217;t create. Stepping down that path only leads to maintenance nightmares going forward.</p>
<p>P.S. If you&#8217;re interested in learning more, check out my presentation on <a href="http://www.slideshare.net/nzakas/scalable-javascript-application-architecture">Scalable JavaScript Application Architecture</a> (<a href="http://developer.yahoo.com/yui/theater/video.php?v=zakas-architecture">video</a>).<br />
<h2>Related posts</h2>
<ul class="related_post">
<li><a href="http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/" title="Custom events in JavaScript">Custom events in JavaScript</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/23/answering-soshnikovs-quiz/" title="Answering Soshnikov&#8217;s quiz">Answering Soshnikov&#8217;s quiz</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/18/my-javascript-quiz-answers/" title="My JavaScript quiz - answers">My JavaScript quiz - answers</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/16/my-javascript-quiz/" title="My JavaScript quiz">My JavaScript quiz</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/09/announcing-high-performance-javascript/" title="Announcing High Performance JavaScript">Announcing High Performance JavaScript</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/02/how-internet-explorer-8-document-mode-affects-javascript/" title="How Internet Explorer 8 document mode affects JavaScript">How Internet Explorer 8 document mode affects JavaScript</a></li>
</ul>
<p>P.S. My new book, <a href="http://www.amazon.com/gp/product/059680279X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=059680279X">High Performance JavaScript</a> is coming out in early 2010. Need help now? Check out <a href="http://www.amazon.com/gp/product/047022780X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=047022780X">Professional JavaScript, 2nd Edition</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=8Gd-HPtkAoU:bhvnzV0Rri0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=8Gd-HPtkAoU:bhvnzV0Rri0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=8Gd-HPtkAoU:bhvnzV0Rri0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=8Gd-HPtkAoU:bhvnzV0Rri0:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=8Gd-HPtkAoU:bhvnzV0Rri0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=8Gd-HPtkAoU:bhvnzV0Rri0:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/8Gd-HPtkAoU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/</feedburner:origLink></item>
		<item>
		<title>Answering Soshnikov’s quiz</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/TMtQ6FN5KiA/</link>
		<comments>http://www.nczonline.net/blog/2010/02/23/answering-soshnikovs-quiz/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 13:00:23 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Quiz]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=2413</guid>
		<description><![CDATA[JavaScript quizzes have sure been popular lately. The latest addition is one by Dmitry A. Soshnikov and is affectionately called, The quiz. I must admit, this quiz has some of the most mind-bending examples of JavaScript I&#8217;ve ever seen. What I like about his quiz is that each piece of code is more or less [...]]]></description>
			<content:encoded><![CDATA[<p>JavaScript quizzes have sure been popular lately. The latest addition is one by <a title="Информация о пользователе." href="http://javascript.ru/person/Dmitry-A.-Soshnikov">Dmitry A. Soshnikov</a> and is affectionately called, <a href="http://dmitrysoshnikov.com/ecmascript/the-quiz/">The quiz</a>. I must admit, this quiz has some of the most mind-bending examples of JavaScript I&#8217;ve ever seen. What I like about his quiz is that each piece of code is more or less reliant on a single JavaScript concept, and that&#8217;s why I&#8217;m spending another week explaining another quiz.</p>
<h2>Question #1</h2>
<pre><code>typeof typeof(null)</code></pre>
<p>This is probably the easiest of all of the questions. Whenever you have <code>typeof typeof</code>, the result is always &#8220;string&#8221;. Why? Because the <code>typeof</code> operator always returns a string value (in this case, it returns &#8220;object&#8221; for <code>typeof(null)</code>).</p>
<h2>Question #2</h2>
<p>Are the algorithms of the following checks completely equivalent?</p>
<pre><code>typeof foo == 'undefined'</code></pre>
<p>and</p>
<pre><code>typeof foo === 'undefined'</code></pre>
<p>The quiz claims that the answer is &#8220;yes&#8221;, though as <a href="http://javascript.ru/blog/Dmitry-A.-Soshnikov/The-quiz#comment-3456">Kangax pointed out</a>, the algorithms for these two operations are actually different. A better way to ask this question would have been, &#8220;is the end result of these two checks completely equivalent?&#8221; The answer to that is a definitive yes because you&#8217;re ultimately comparing two strings in each comparison. When comparing two strings, the == operator doesn&#8217;t do any type coercion and so the two comparisons will always return the same result.</p>
<h2>Question #3</h2>
<p>What&#8217;s the result of:</p>
<pre><code>100['toString']['length']</code></pre>
<p>A couple of good pieces of deception in this one. Numbers end up wrapped by the <code>Number</code> type when you use them, and the <code>Number</code> type has a <code>toString()</code> method. However, you&#8217;re not actually calling <code>toString()</code> in this case, you&#8217;re actually accessing the <code>length</code> property of the <code>toString()</code> method. It makes more sense to look at the code like this:</p>
<pre><code>100.toString.length</code></pre>
<p>The <code>length</code> property of a function indicates how many names arguments are expected. The <code>toString()</code> methods accepts one argument, which is the radix in which to output the string representation of the number (for example <code>toString(2)</code> outputs the binary representation of the number as a string and <code>toString(16)</code> outputs the hexadecimal representation of the number as a string).</p>
<p>So the answer to this question is 1.</p>
<h2>Question #4</h2>
<p>What&#8217;s the result of:</p>
<pre><code>var a = (1,5 - 1) * 2</code></pre>
<p>This is the first question that relies on your knowledge of how the comma operator works. To put it simply: when there&#8217;s an expression containing one or more commas, the value of the expression is equal to the last value. For example, the value of <code>(1,2,3,4)</code> is 4 and the value of <code>("hello", "world")</code> is &#8220;world&#8221;. The comma operator&#8217;s best use is in defining multiple variables and the example usage here is definitely not recommended.</p>
<p>Given this knowledge, it should be obvious that the answer to this question is 8. That&#8217;s because <code>(1,5-1)</code> gets evaluated to <code>(1,4)</code> so the final value is 4. I&#8217;m sure you can take it from there.</p>
<h2>Question #5</h2>
<p>What&#8217;s the result of:</p>
<pre><code>var x = 10;
var foo = {
  x: 20,
  bar: function () {
    var x = 30;
    return this.x;
  }
};

console.log(
  foo.bar(),
  (foo.bar)(),
  (foo.bar = foo.bar)(),
  (foo.bar, foo.bar)()
);</code></pre>
<p>This code outputs four values onto the console. The real question is what are the four values. It should be very obvious that the first value is 20 because <code>foo.bar()</code> accesses <code>this.x</code> on <code>foo</code>, which is 20. The next part, <code>(foo.bar)()</code> acts in the exact same way as <code>foo.bar()</code>. Wrapping <code>foo.bar</code> in parens doesn&#8217;t change how it&#8217;s evaluated. This also outputs 20.</p>
<p>The tricky part comes next. The return value of an assignment expression is always the right-hand side expression. Assigning a function to a location, even if it&#8217;s the same location from where it came, results in the overall expression having a value of the function. The important piece of information is that the function now has no context object associated with it, so <code>(foo.bar = foo.bar)()</code> executes as if it where <code>foo.bar.call()</code>. Of course, any function called outside of an object context gets executed in the context of the global, so <code>this.x</code> now is 10. Thus, the third part outputs 10.</p>
<p>The fourth variation outputs the same result as the third. Once again you encounter the comma operator. Keep in mind that <code>foo.bar</code> in this part of the code represents a pointer to the function, and the comma operator takes on the value of that function before being called. This outputs the same value as the previous section for the same reason: using the comma operator means the function is context-free and gets executed in the global scope.</p>
<p>So your overall answer: <code>20 20 10 10</code>.</p>
<h2>Question #6</h2>
<p>What&#8217;s the result of:</p>
<pre><code>function f(x, y) {
  x = 10;
  console.log(
    arguments[0],
    arguments[1]
  );
}

f();</code></pre>
<p>This function has two named arguments but neither are provided when the function is called. You should know that the value of these named arguments will be <code>undefined</code> in this case, and so outputting <code>arguments[1]</code> should also obviously be <code>undefined</code>. The only question, then, is the value of <code>arguments[0]</code>. This actually tests the inverse of what Baranovskiy&#8217;s fourth question tested. In his test, Barnovskiy changed a value in the <code>arguments</code> object and you saw that the corresponding named argument changed in value as well (see my <a href="http://www.nczonline.net/blog/2010/01/26/answering-baranovskiys-javascript-quiz/">writeup</a> for more info). The opposite, however, is not true.</p>
<p>Changing the named argument&#8217;s value does not automatically change the corresponding value in <code>arguments</code>. As mentioned in my aforementioned post, the <code>arguments</code> object and the named argument do not share memory space. When a change is made to <code>arguments</code>, that value is <em>copied</em> to the named argument. It doesn&#8217;t work the other way. A named argument is no more special than a local variable, and so changing its value doesn&#8217;t affect the <code>arguments</code> object. So, <code>arguments[0]</code> is still <code>undefined</code> and the output of the code is <code>undefined undefined</code>.</p>
<h2>Question #7</h2>
<p>What&#8217;s the result of:</p>
<pre><code>var
  b = 10,
  c = (
    20,
    function (x) { return x + 100},
    function () { return arguments[0]}
  );

a = b + c
({x: 10}).x</code></pre>
<p>There are only two concepts that you need to understand to answer this. The first is how the comma operator works, which you should be an expert in by now. The value of <code>c</code> is the function <code>function(){ return arguments[0];}</code>, which just returns the first argument that was passed in.</p>
<p>The second thing you need to know is how automatic semicolon insertion works. Because of the way the code is formatted, you might be inclined to believe that a semicolon will be inserted after <code>a = b + c</code>. Keep in mind that <code>c</code> is a function, and the next non-whitespace character is <code>(</code>. In this case, the whitespace is ignored, so the last line is actually:</p>
<pre><code>a = b + c({x: 10}).x</code></pre>
<p>Since the function contained in <code>c</code> simply passes back the argument that was passed in, the result of this expression is logically equivalent to:</p>
<pre><code>a = b + ({x: 10}).x</code></pre>
<p>And that is really just:</p>
<pre><code>a = b + 10</code></pre>
<p>This makes <code>a</code> equal to 20, and that is the final value of the code.</p>
<h2>Question #8</h2>
<p>What&#8217;s the result of:</p>
<pre><code>1..z</code></pre>
<p>Another sneaky question. At first glance, this looks like an obvious syntax error. However, there is no syntax error here because of the way this text is parsed. Remember from earlier that numbers end up wrapped by the <code>Number</code> type when accessed, which makes an ad-hoc object. The <code>z</code> in this case is attempting to access a property, which means the code could be written as:</p>
<pre><code>(1.)["z"]</code></pre>
<p>So what is <code>1.</code>? It&#8217;s actually a valid floating-point number in JavaScript. JavaScript unfortunately allows trailing decimal points on numbers, so you can have <code>1</code> or <code>1.</code> or <code>1.0</code> depending on how you feel like writing the code. Trailing decimal points are considered bad practice and are a warning when code is run through <a href="http://www.jslint.com">JSLint</a>.</p>
<p>Really, this question is asking you for the value of the property <code>z</code> on this number object representing <code>1.</code>. Since there is no such property on <code>Number</code> objects, the value is <code>undefined</code>.</p>
<h2>Question #9</h2>
<p>What&#8217;s the result of:</p>
<pre><code>({
  x: 10,
  foo: function () {
    function bar() {
      console.log(x);
      console.log(y);
      console.log(this.x);
    }
    with (this) {
      var x = 20;
      var y = 30;
      bar.call(this);
    }
  }
}).foo();</code></pre>
<p>Another tricky one that tests your understanding of <code>with</code> statements. There&#8217;s really only one concept to grasp to get this question right, and that&#8217;s what <code>var</code> statements in <code>with</code> statements actually do. There are essentially three scenarios:</p>
<ol>
<li>The variable being declared doesn&#8217;t exist as a property on the context object (in this case, <code>this</code>) and the variable doesn&#8217;t exist as a local variable of the containing function (<code>foo()</code>). In this case, the variable declaration creates a new local variable to the containing function. This happens due to <code>var</code> statement hoisting (also described in my <a href="http://www.nczonline.net/blog/2010/01/26/answering-baranovskiys-javascript-quiz/">previous post</a>).</li>
<li>The variable being declared exists as a property on the context object. Two things actually happen here. First, the <code>var</code> statement is hoisted and a new local variable is defined. The initialization statement, however, stays in the same location and thus assigns the value to the object property with the same name.</li>
<li>The variable being declared exists as a local variable of the containing function. In this case, the existing variable is simply assigned the given value.</li>
</ol>
<p>Armed with this knowledge, you can determine the three values that are output. First, <code>x</code> is declared but never assigned a value. Due to <code>var</code> hoisting, the <code>with</code> statement is effectively the same as this:</p>
<pre><code>var x;
var y;
with (this) {
    x = 20;
    y = 30;
    bar.call(this);
}</code></pre>
<p>So <code>var x = 20;</code> gets mapped to <code>this.x = 20;</code> inside of the <code>with</code> statement since <code>x</code> exists as a property of the context object <code>this</code>. That means <code>this.x</code> changes from 10 to 20 while the local variable <code>x</code> is never assigned a value.</p>
<p>The function <code>bar()</code> is a closure inside of <code>foo()</code>, and therefore has access to all of <code>foo()</code>&#8217;s local variables (which are <code>x</code> and <code>y</code>). When <code>console.log(x)</code> is executed, it outputs <code>undefined</code> because the variable <code>x</code> was never initialized (all variables are assigned the value <code>undefined</code> when declared).</p>
<p>Next, <code>y</code> is assigned a value of 30, creating a local variable in <code>foo()</code>. Since <code>bar()</code> is a closure, it has access to all local variables of <code>foo()</code>y.</p>
<p>The last part, <code>console.log(this.x);</code> outputs 20 because the function is called in the context of the object.</p>
<p>So there&#8217;s your answer: <code>undefined</code>, <code>30</code>, <code>20</code>.</p>
<h2>Question #10</h2>
<p>What&#8217;s the result of:</p>
<pre><code>foreach (k in {a: 10, b: 20})
{
  // ...
}</code></pre>
<p>Another tricky one since <code>foreach-in</code> isn&#8217;t defined in <a href="http://www.ecma-international.org/publications/standards/Ecma-262.HTM">ECMA-262</a>. There is a <code>for-each-in</code> statement defined in <a href="http://www.ecma-international.org/publications/standards/Ecma-357.htm">ECMA-357</a> (ECMAScript for XML) and, in that spec, it is used to iterate over the values in an array. So the trick here is that knowing too much about JavaScript could actually lead to the wrong answer.</p>
<p>Since there is no <code>foreach-in</code> statement implemented anywhere, this should cause an error. You might think it would cause a syntax error but it won&#8217;t because <code>foreach</code> is a valid identifier (it&#8217;s not a keyword and follows the identifier format), so the JavaScript engine looks for a reference to <code>foreach</code> and, unable to find it, throws a <code>ReferenceError</code>.</p>
<p>The &#8220;correct&#8221; answer for this one is a point of contention. I would argue that the answer should &#8220;always ReferenceError&#8221; because if you run just this code in the example, this is what you get. The author says that the answer is actually &#8220;ReferenceError or possibly no error&#8221; because if <code>foreach()</code> and <code>k</code> are both defined previously, this won&#8217;t throw an error. Since all of the other questions hinge on just the code presented, I don&#8217;t think it&#8217;s a fair jump to ask people to make. However, to be as complete as possible, let&#8217;s assume the code is this:</p>
<pre><code>function foreach(){
    //do something
}
var k = "a";

foreach (k in {a: 10, b: 20})
{
  // ...
}</code></pre>
<p>With this code, you would receive no errors whatsoever. Why? Because <code>foreach(k in {a: 10, b: 20})</code> evaluates to <code>foreach(true)</code> because the property &#8220;a&#8221; does exist in the given object literal. But what about the remaining curly braces?</p>
<p>This is another trick of automatic semicolon insertion. The format of the code looks like the braces represent the body of a statement, however, they actually represent an empty object literal. The code is interpreted as:</p>
<pre><code>function foreach(){
    //do something
}
var k = "a";

foreach (k in {a: 10, b: 20});

{
  // ...
};</code></pre>
<p>Note that a semicolon is inserted before the left curly brace and after the right curly brace. These are actually two separate and unrelated statements once the semicolons have been inserted. An object literal that isn&#8217;t assigned to a variable might look weird, but it&#8217;s still a valid statement, just like any of the following:</p>
<pre><code>"hello world";
5;
true;</code></pre>
<p>A statement doesn&#8217;t have to execute a function or assign a value, it may just contain a value.</p>
<h2>Wrapping up</h2>
<p>I really liked this quiz because of its high level of difficulty. Hopefully now you understand better how the comma operator works and some of the semantics around variable declaration hoisting.<br />
<h2>Related posts</h2>
<ul class="related_post">
<li><a href="http://www.nczonline.net/blog/2010/02/18/my-javascript-quiz-answers/" title="My JavaScript quiz - answers">My JavaScript quiz - answers</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/16/my-javascript-quiz/" title="My JavaScript quiz">My JavaScript quiz</a></li>
<li><a href="http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/" title="Custom events in JavaScript">Custom events in JavaScript</a></li>
<li><a href="http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/" title="Maintainable JavaScript: Don&#8217;t modify objects you don&#8217;t own">Maintainable JavaScript: Don&#8217;t modify objects you don&#8217;t own</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/09/announcing-high-performance-javascript/" title="Announcing High Performance JavaScript">Announcing High Performance JavaScript</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/02/how-internet-explorer-8-document-mode-affects-javascript/" title="How Internet Explorer 8 document mode affects JavaScript">How Internet Explorer 8 document mode affects JavaScript</a></li>
</ul>
<p>P.S. My new book, <a href="http://www.amazon.com/gp/product/059680279X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=059680279X">High Performance JavaScript</a> is coming out in early 2010. Need help now? Check out <a href="http://www.amazon.com/gp/product/047022780X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=047022780X">Professional JavaScript, 2nd Edition</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=TMtQ6FN5KiA:u7TDDITTrXM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=TMtQ6FN5KiA:u7TDDITTrXM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=TMtQ6FN5KiA:u7TDDITTrXM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=TMtQ6FN5KiA:u7TDDITTrXM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=TMtQ6FN5KiA:u7TDDITTrXM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=TMtQ6FN5KiA:u7TDDITTrXM:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/TMtQ6FN5KiA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2010/02/23/answering-soshnikovs-quiz/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.nczonline.net/blog/2010/02/23/answering-soshnikovs-quiz/</feedburner:origLink></item>
		<item>
		<title>My JavaScript quiz - answers</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/5_RmJCDU7gE/</link>
		<comments>http://www.nczonline.net/blog/2010/02/18/my-javascript-quiz-answers/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 13:00:12 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Quiz]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=2404</guid>
		<description><![CDATA[Earlier this week, I posted my JavaScript quiz, containing some basic code along with questions. Here are the answers.
Example #1
var num1 = 5,
    num2 = 10,
    result = num1+++num2;
The key to understanding this example is to understand operator precedence. Clearly, +++ isn&#8217;t a valid operator, so the JavaScript engine [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier this week, I posted <a href="http://www.nczonline.net/blog/2010/02/16/my-javascript-quiz/">my JavaScript quiz</a>, containing some basic code along with questions. Here are the answers.</p>
<h2>Example #1</h2>
<pre><code>var num1 = 5,
    num2 = 10,
    result = num1+++num2;</code></pre>
<p>The key to understanding this example is to understand operator precedence. Clearly, +++ isn&#8217;t a valid operator, so the JavaScript engine breaks it up into a postfix increment operator and the plus sign. This code is completely valid and parses without problem, but really could be written like this:</p>
<pre><code>var num1 = 5,
    num2 = 10,
    result = num1++ + num2;</code></pre>
<p>With the understanding that this is how the code is interpreted, the questions should be fairly easy.</p>
<ul>
<li><strong>What is the value of <code>result</code>? </strong>The value is 15 because the postfix increment works after the <code>num1+++num2</code> statement has executed.</li>
<li><strong>What is the value of <code>num1</code>?</strong> The value is 6 because it is incremented after the last statement.</li>
<li><strong>What is the value of <code>num2</code>?</strong> The value is 10 because no operation takes place on <code>num2</code> itself.</li>
</ul>
<h2>Example #2</h2>
<pre><code>var x = 5,
    o = {
        x: 10,
        doIt: function doIt(){
            var x = 20;
            setTimeout(function(){
                alert(this.x);
            }, 10);
        }
    };
o.doIt();</code></pre>
<p>The key to this example is understanding JavaScript scope. The alert inside of the closure references this.x, but because this reference is wrapped in a couple of functions inside of an object, what is the correct scope? The answer is pretty simple. All functions passed into <code>setTimeout()</code> are executed in the global scope.</p>
<ul>
<li><strong>What value is displayed in the alert? </strong>The value is 5 because <code>this.x</code> is the same as <code>window.x</code> and <code>var x = 5</code> is equivalent to <code>window.x = 5</code>.</li>
</ul>
<h2>Example #3</h2>
<pre><code>var num1 = "10",
    num2 = "9";</code></pre>
<p>The code is pretty self-explanatory, just two string variables being defined.</p>
<ul>
<li><strong>What is the value of <code>num1 &lt; num2</code>?</strong> When both operands are strings, comparison operators perform string comparisons by comparing characters in the same position. The string &#8220;10&#8243; comes before the string &#8220;9&#8243; because the character &#8220;1&#8243; comes before the character &#8220;9&#8243; in ASCII. Since there are no more characters to compare after that point, this comparison is the one that remains. Thus, the value of <code>num1 &lt; num2</code> is <code>true</code>.</li>
<li><strong>What is the value of <code>+num1 &lt; num2</code>?</strong> The plus operator here converts <code>num1</code> into a number, so now you&#8217;re comparing a number to a string. When this happens, the string operator gets converted into a number and then the comparison commences. So ultimately this is equivalent to 10 &lt; 9, which very obviously is <code>false</code>.</li>
<li><strong>What is the value of <code>num1 + num2</code>?</strong> Both operands are strings, which means a string concatenation happens. The result is <code>"109"</code>.</li>
<li><strong>What is the value of <code>+num1 + num2</code>?</strong> As you saw earlier, the plus operator converts a string to number, so <code>num1</code> becomes the number 10. However, when the plus operator is used with a number and a string, the number gets converted to a string and then string concatenation is performed. So the result of this is the same as if you did <code>num1 + num2</code> as the value is <code>"109"</code>.</li>
</ul>
<h2>Example #4</h2>
<pre><code>var message = "Hello world!";</code></pre>
<p>Just a simple string variable, nothing fancy here.</p>
<ul>
<li><strong>What is the value of <code>message.substring(1, 4)</code>?</strong> The first argument is the index of the first character you want and the second argument is the index of the character <em>after</em> the last one you want. In this case, you want the second character (index 1) through the fourth character (index 3). So the result is &#8220;ell&#8221;.</li>
<li><strong>What is the value of <code>message.substr(1,4)</code>?</strong> The first argument is the index of the first character you want and the second argument is how many characters to retrieve. In this case, you want the second character (index 1) and then three more characters, so the result is &#8220;ello&#8221;.</li>
</ul>
<h2>Example #5</h2>
<pre><code>var o = {
        x: 8,

        valueOf: function(){
            return this.x + 2;
        },
        toString: function(){
            return this.x.toString();
        }
    },
    result = o &lt; "9";

alert(o);</code></pre>
<p>This is perhaps the most difficult of the code examples because you need to understand how <code>valueOf()</code> and <code>toString()</code> work. All objects have these two methods as they are defined on <code>Object.prototype</code> and inherited through the prototype chain (nitpickers will note that it&#8217;s possible to have objects that don&#8217;t inherit from <code>Object</code>, but I&#8217;m trying to keep this simple). These two methods get called behind-the-scenes all the time. The <code>valueOf()</code> method is called whenever comparisons are done and <code>toString()</code> is called whenever automatic conversion into a string is necessary. By overriding these methods, you can control the values they return in various circumstances.</p>
<ul>
<li><strong>What is the value <code>result</code>?</strong> The <code>valueOf()</code> method gets called behind-the-scenes here, so really the comparison is 10 &lt; &#8220;9&#8243;. As you learned earlier, a comparison between a number and a string causes the string to be converted into a number, so the comparison ends up being 10 &lt; 9, which is <code>false</code>.</li>
<li><strong>What is the value displayed in the alert?</strong> Values passed into <code>alert()</code> are converted to strings, which means that <code>toString()</code> gets called. The alert, therefore, displays <code>"8"</code>.</li>
</ul>
<h2>That&#8217;s it!</h2>
<p>I hope you&#8217;ve enjoyed this little JavaScript quiz and hopefully learned a thing or two.</p>
<p><strong>Update (18-Feb-2010):</strong> Fixed typo in answer #1.<br />
<h2>Related posts</h2>
<ul class="related_post">
<li><a href="http://www.nczonline.net/blog/2010/02/23/answering-soshnikovs-quiz/" title="Answering Soshnikov&#8217;s quiz">Answering Soshnikov&#8217;s quiz</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/16/my-javascript-quiz/" title="My JavaScript quiz">My JavaScript quiz</a></li>
<li><a href="http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/" title="Custom events in JavaScript">Custom events in JavaScript</a></li>
<li><a href="http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/" title="Maintainable JavaScript: Don&#8217;t modify objects you don&#8217;t own">Maintainable JavaScript: Don&#8217;t modify objects you don&#8217;t own</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/09/announcing-high-performance-javascript/" title="Announcing High Performance JavaScript">Announcing High Performance JavaScript</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/02/how-internet-explorer-8-document-mode-affects-javascript/" title="How Internet Explorer 8 document mode affects JavaScript">How Internet Explorer 8 document mode affects JavaScript</a></li>
</ul>
<p>P.S. My new book, <a href="http://www.amazon.com/gp/product/059680279X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=059680279X">High Performance JavaScript</a> is coming out in early 2010. Need help now? Check out <a href="http://www.amazon.com/gp/product/047022780X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=047022780X">Professional JavaScript, 2nd Edition</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=5_RmJCDU7gE:auVvXzlLpHI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=5_RmJCDU7gE:auVvXzlLpHI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=5_RmJCDU7gE:auVvXzlLpHI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=5_RmJCDU7gE:auVvXzlLpHI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=5_RmJCDU7gE:auVvXzlLpHI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=5_RmJCDU7gE:auVvXzlLpHI:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/5_RmJCDU7gE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2010/02/18/my-javascript-quiz-answers/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.nczonline.net/blog/2010/02/18/my-javascript-quiz-answers/</feedburner:origLink></item>
		<item>
		<title>My JavaScript quiz</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/LLqnEt2TPOU/</link>
		<comments>http://www.nczonline.net/blog/2010/02/16/my-javascript-quiz/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 13:00:29 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Quiz]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=2399</guid>
		<description><![CDATA[Recently, there have been a couple of JavaScript quizzes floating around. There was one by Dmitry Baranovskiy (for which I explained the answers) and one by Kangax. But there are so many strange pieces of JavaScript that I thought I&#8217;d put together a quiz of my own. I&#8217;ve decided that each part will be a [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, there have been a couple of JavaScript quizzes floating around. There was one by <a href="http://dmitry.baranovskiy.com/post/91403200">Dmitry Baranovskiy</a> (for which I <a href="http://www.nczonline.net/blog/2010/01/26/answering-baranovskiys-javascript-quiz/">explained</a> the answers) and one by <a href="http://perfectionkills.com/javascript-quiz/">Kangax</a>. But there are so many strange pieces of JavaScript that I thought I&#8217;d put together a quiz of my own. I&#8217;ve decided that each part will be a single code example followed by one or more questions. Once again, I don&#8217;t think such quizzes are useful for job interviews, but they are fun to test the depths of your knowledge. Without further adieu, here it is (answers to follow by end of week).</p>
<h2>Example #1</h2>
<pre><code>var num1 = 5,
    num2 = 10,
    result = num1+++num2;</code></pre>
<p>Questions:</p>
<ul>
<li>What is the value of <code>result</code>?</li>
<li>What is the value of <code>num1</code>?</li>
<li>What is the value of <code>num2</code>?</li>
</ul>
<h2>Example #2</h2>
<pre><code>var x = 5,
    o = {
        x: 10,
        doIt: function doIt(){
            var x = 20;
            setTimeout(function(){
                alert(this.x);
            }, 10);
        }
    };
o.doIt();</code></pre>
<p>Questions:</p>
<ul>
<li>What value is displayed in the alert?</li>
</ul>
<h2>Example #3</h2>
<pre><code>var num1 = "10",
    num2 = "9";</code></pre>
<p>Questions:</p>
<ul>
<li>What is the value of <code>num1 &lt; num2</code>?</li>
<li>What is the value of <code>+num1 &lt; num2</code>?</li>
<li>What is the value of <code>num1 + num2</code>?</li>
<li>What is the value of <code>+num1 + num2</code>?</li>
</ul>
<h2>Example #4</h2>
<pre><code>var message = "Hello world!";</code></pre>
<p>Questions:</p>
<ul>
<li>What is the value of <code>message.substring(1, 4)</code>?</li>
<li>What is the value of <code>message.substr(1,4)</code>?</li>
</ul>
<h2>Example #5</h2>
<pre><code>var o = {
        x: 8,

        valueOf: function(){
            return this.x + 2;
        },
        toString: function(){
            return this.x.toString();
        }
    },
    result = o &lt; "9";

alert(o);</code></pre>
<p>Questions:</p>
<ul>
<li>What is the value <code>result</code>?</li>
<li>What is the value displayed in the alert?</li>
</ul>
<h2>That&#8217;s it!</h2>
<p>Whereas the other quizzes might have made your eyes cross trying to trace scope changes and the like, I wanted this one to be as dead simple as possible. The point? JavaScript is complex enough when written simply. Try to answer the questions without running the code. Answers with complete explanations will follow soon.<br />
<h2>Related posts</h2>
<ul class="related_post">
<li><a href="http://www.nczonline.net/blog/2010/02/23/answering-soshnikovs-quiz/" title="Answering Soshnikov&#8217;s quiz">Answering Soshnikov&#8217;s quiz</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/18/my-javascript-quiz-answers/" title="My JavaScript quiz - answers">My JavaScript quiz - answers</a></li>
<li><a href="http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/" title="Custom events in JavaScript">Custom events in JavaScript</a></li>
<li><a href="http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/" title="Maintainable JavaScript: Don&#8217;t modify objects you don&#8217;t own">Maintainable JavaScript: Don&#8217;t modify objects you don&#8217;t own</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/09/announcing-high-performance-javascript/" title="Announcing High Performance JavaScript">Announcing High Performance JavaScript</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/02/how-internet-explorer-8-document-mode-affects-javascript/" title="How Internet Explorer 8 document mode affects JavaScript">How Internet Explorer 8 document mode affects JavaScript</a></li>
</ul>
<p>P.S. My new book, <a href="http://www.amazon.com/gp/product/059680279X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=059680279X">High Performance JavaScript</a> is coming out in early 2010. Need help now? Check out <a href="http://www.amazon.com/gp/product/047022780X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=047022780X">Professional JavaScript, 2nd Edition</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=LLqnEt2TPOU:SOrM8nWhkvI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=LLqnEt2TPOU:SOrM8nWhkvI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=LLqnEt2TPOU:SOrM8nWhkvI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=LLqnEt2TPOU:SOrM8nWhkvI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=LLqnEt2TPOU:SOrM8nWhkvI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=LLqnEt2TPOU:SOrM8nWhkvI:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/LLqnEt2TPOU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2010/02/16/my-javascript-quiz/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.nczonline.net/blog/2010/02/16/my-javascript-quiz/</feedburner:origLink></item>
		<item>
		<title>Announcing High Performance JavaScript</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/G9xaketnsds/</link>
		<comments>http://www.nczonline.net/blog/2010/02/09/announcing-high-performance-javascript/#comments</comments>
		<pubDate>Tue, 09 Feb 2010 13:00:51 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[Books]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Performance]]></category>

		<category><![CDATA[Writing]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=2394</guid>
		<description><![CDATA[Last year was one in which I did a lot of research on performance, resulting in the Speed Up Your JavaScript blog post series (part 1, part 2, part 3, part 4) as well as several talks, namely JavaScript Variable Performance at the San Francisco JavaScript Meetup, Speed Up Your JavaScript at Google (video), and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/gp/product/059680279X?ie=UTF8&amp;tag=nczonline-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=059680279X"><img style="padding:10px" src="http://i764.photobucket.com/albums/xx289/nzakas/nczonline/hpjs_big.png" alt="High Performance JavaScript Book Cover" width="180" height="236" align="right" /></a>Last year was one in which I did a lot of research on performance, resulting in the Speed Up Your JavaScript blog post series (<a href="http://www.nczonline.net/blog/2009/01/13/speed-up-your-javascript-part-1/">part 1</a>, <a href="http://www.nczonline.net/blog/2009/01/20/speed-up-your-javascript-part-2/">part 2</a>, <a href="http://www.nczonline.net/blog/2009/01/27/speed-up-your-javascript-part-3/">part 3</a>, <a href="http://www.nczonline.net/blog/2009/02/03/speed-up-your-javascript-part-4/">part 4</a>) as well as several talks, namely <a href="http://www.slideshare.net/nzakas/java-script-variable-performance-presentation">JavaScript Variable Performance</a> at the San Francisco JavaScript Meetup, <a href="http://www.slideshare.net/nzakas/speed-up-your-javascript">Speed Up Your JavaScript</a> at Google (<a href="http://www.youtube.com/watch?v=mHtdZgou0qU">video</a>), and <a href="http://www.slideshare.net/nzakas/writing-efficient-javascript">Writing Efficient JavaScript</a> at Velocity. I was then asked my <a href="http://www.stevesouders.com">Steve Souders</a> to contribute a chapter on JavaScript performance to his book, <a href="http://www.amazon.com/gp/product/0596522304?ie=UTF8&amp;tag=nczonline-20&amp;link_code=as3&amp;camp=211189&amp;creative=373489&amp;creativeASIN=0596522304">Even Faster Web Sites</a>. While writing that chapter, I felt like I had far too little space to explore so wide of a topic.</p>
<p>Not long after that, I was approached by Havi Hoffman of the <a href="http://developer.yahoo.com">Yahoo! Developer Network</a> to see if I would be interested in writing a book on JavaScript performance to be published by <a href="http://developer.yahoo.com/yahoopress/">Yahoo! Press</a>. You may be familiar with the first Yahoo! Press book, <a href="http://www.amazon.com/gp/product/0596517742?ie=UTF8&amp;tag=nczonline-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0596517742">JavaScript: The Good Parts</a> by Douglas Crockford, but there&#8217;s also <a href="http://www.amazon.com/gp/product/0596521979?ie=UTF8&amp;tag=nczonline-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0596521979">Hadoop: The Definitive Guide</a> (Tom White) and <a href="http://www.amazon.com/gp/product/0596154925?ie=UTF8&amp;tag=nczonline-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0596154925">Designing Social Interfaces</a> (Christian Crumlish &amp; Erin Malone). Each features invaluable knowledge from some of Yahoo!&#8217;s best and brightest. I have to admit that it was a dream of mine to write for Yahoo! since I first joined the company, and this was the perfect opportunity.</p>
<p>In March, <a href="http://www.amazon.com/gp/product/059680279X?ie=UTF8&amp;tag=nczonline-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=059680279X">High Performance JavaScript</a> will officially hit the shelves (it&#8217;s available for pre-order now on Amazon). My vision for this book was to expand upon the chapter I wrote in  <a href="http://www.amazon.com/gp/product/0596522304?ie=UTF8&amp;tag=nczonline-20&amp;link_code=as3&amp;camp=211189&amp;creative=373489&amp;creativeASIN=0596522304">Even Faster Web Sites</a> and wanted very much to keep the overall statistics-driven approach that Steve had employed. But in order to make this book the absolute best that it could be, I also borrowed Steve&#8217;s idea and sought out some of the smartest engineers I know to contribute to the book. So this book features chapters written by the following:</p>
<ul>
<li><a href="http://techfoolery.com/">Ross Harmes</a>, co-author of <a href="http://www.amazon.com/gp/product/159059908X?ie=UTF8&amp;tag=nczonline-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=159059908X">Pro JavaScript Design Patterns</a> and front-end engineer for <a href="http://www.flickr.com">Flickr</a>. Ross writes about Ajax performance with an eye on squeezing out the fastest client-server messaging possible.</li>
<li><a href="http://www.julienlecomte.net/">Julien Lecomte</a>, creator of the YUI Compressor and front-end engineer on <a href="http://search.yahoo.com">Yahoo! Search</a>. Julien describes effectively deploying your JavaScript with performance in mind.</li>
<li><a href="http://blog.stevenlevithan.com/">Steven Levithan</a>, co-author of the <a href="http://www.amazon.com/gp/product/0596520689?ie=UTF8&amp;tag=nczonline-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0596520689">Regular Expression Cookbook</a> and guru on all things related to strings and regular expressions. Steven explains the ins and outs of string and regular expression performance in JavaScript in a way that I believe has never been done before. He&#8217;s also running a <a href="http://blog.stevenlevithan.com/archives/high-performance-javascript">contest</a> to win a free copy of the book.</li>
<li>Matt Sweeney, <a href="http://developer.yahoo.com/yui/3/">YUI 3</a> architect. Matt focuses on currently available tools for measuring JavaScript performance.</li>
<li><a href="http://www.phpied.com">Stoyan Stefanov</a>, author of <a href="http://www.amazon.com/gp/product/1847194141?ie=UTF8&amp;tag=nczonline-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1847194141">Object-Oriented JavaScript</a> and front-end engineer on <a href="http://search.yahoo.com">Yahoo! Search</a>. Stoyan investigates the performance of the DOM and how reflows and repaints affect JavaScript&#8217;s perceived performance. This chapter, to me, will be the definitive print resource for reflow information.</li>
</ul>
<p>Of course, there&#8217;s also five chapters written by me, making this a ten-chapter intensive look at JavaScript performance in the browser. I tried to make sure we covered all angles of the JavaScript lifecycle, from getting the code onto the page, executing the code, and deploying into production. I&#8217;m very, very excited about this book and the positive impact it can have on JavaScript developers. Don&#8217;t be fooled by faster JavaScript engines, JavaScript performance is going to continue to be important to understand for years to come. I hope you enjoy the book!<br />
<h2>Related posts</h2>
<ul class="related_post">
<li><a href="http://www.nczonline.net/blog/2009/03/28/announcing-even-faster-web-sites/" title="Announcing Even Faster Web Sites">Announcing Even Faster Web Sites</a></li>
<li><a href="http://www.nczonline.net/blog/2008/11/11/professional-javascript-2nd-edition-available-for-pre-order/" title="Professional JavaScript, 2nd Edition available for pre-order">Professional JavaScript, 2nd Edition available for pre-order</a></li>
<li><a href="http://www.nczonline.net/blog/2006/02/19/respect-javascript/" title="Respect JavaScript">Respect JavaScript</a></li>
<li><a href="http://www.nczonline.net/blog/2005/01/14/kind-words/" title="Kind Words">Kind Words</a></li>
<li><a href="http://www.nczonline.net/blog/2009/08/11/timed-array-processing-in-javascript/" title="Timed array processing in JavaScript">Timed array processing in JavaScript</a></li>
<li><a href="http://www.nczonline.net/blog/2009/07/28/the-best-way-to-load-external-javascript/" title="The best way to load external JavaScript">The best way to load external JavaScript</a></li>
</ul>
<p>P.S. My new book, <a href="http://www.amazon.com/gp/product/059680279X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=059680279X">High Performance JavaScript</a> is coming out in early 2010. Need help now? Check out <a href="http://www.amazon.com/gp/product/047022780X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=047022780X">Professional JavaScript, 2nd Edition</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=G9xaketnsds:-bE12qp3R4Q:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=G9xaketnsds:-bE12qp3R4Q:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=G9xaketnsds:-bE12qp3R4Q:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=G9xaketnsds:-bE12qp3R4Q:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=G9xaketnsds:-bE12qp3R4Q:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=G9xaketnsds:-bE12qp3R4Q:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/G9xaketnsds" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2010/02/09/announcing-high-performance-javascript/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.nczonline.net/blog/2010/02/09/announcing-high-performance-javascript/</feedburner:origLink></item>
		<item>
		<title>How Internet Explorer 8 document mode affects JavaScript</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/Tn7FT-QLK1s/</link>
		<comments>http://www.nczonline.net/blog/2010/02/02/how-internet-explorer-8-document-mode-affects-javascript/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 13:00:30 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[Arrays]]></category>

		<category><![CDATA[Internet Explorer]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=2392</guid>
		<description><![CDATA[In a previous post, I talked about Internet Explorer 8&#8217;s wide array of browser and document modes. Most people are pretty familiar with how the various document modes affect layout in terms of how CSS is implemented, but what has been lost is how the document mode affects the core JavaScript engine in the browser. [...]]]></description>
			<content:encoded><![CDATA[<p>In a previous post, I talked about Internet Explorer 8&#8217;s wide array of <a href="http://www.nczonline.net/blog/2010/01/19/internet-explorer-8-document-and-browser-modes/">browser and document modes</a>. Most people are pretty familiar with how the various document modes affect layout in terms of how CSS is implemented, but what has been lost is how the document mode affects the core JavaScript engine in the browser. These changes are somewhat subtle, but important to understand when you&#8217;re working with Internet Explorer 8.</p>
<p>A couple of years ago, Microsoft published a paper called, <a href="http://wiki.ecmascript.org/lib/exe/fetch.php?id=resources%3Aresources&amp;cache=cache&amp;media=resources:jscriptdeviationsfromes3.pdf">JScript Deviations from ES3</a>, in which they outlined ways in which the JScript engine (the one power Internet Explorer&#8217;s JavaScript) had deviated from the ECMAScript 3 standard. These deviations are somewhat innocuous, but chances are that you&#8217;ve been bitten by one or more of them at some point in the past. In Microsoft&#8217;s attempt to make Internet Explorer 8 more standards-compliant, the same issues that arose around CSS also arose around JavaScript. They could fix the deviations in JScript, but if the browser were running in IE5 or IE7 document modes, there could be problems as these fixes might be incompatible with the code targeting those browsers.</p>
<p>Microsoft chose to create <a href="http://blogs.msdn.com/jscript/archive/2009/04/17/versioning-language-features-in-jscript.aspx">versioned features of the JScript engine</a> for Internet Explorer 8. For IE5 and IE7 document modes, the JScript engine acts as it did in the actual Internet Explorer 7, complete with all deviations from ECMAScript 3. When in IE8 document mode, the deviations are gone and you get the full power of the JScript engine.</p>
<h2>Native JSON</h2>
<p>Internet Explorer 8&#8217;s JScript engine implements the native <code>JSON</code> object object as defined by <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMAScript 5</a>. The object is only present, however, when the page is running in IE8 document mode. This includes the global <code>JSON</code> object as well as methods used for JSON functionality:</p>
<ul>
<li><code>Date.prototype.toJSON()</code></li>
<li><code>Number.prototype.toJSON()</code></li>
<li><code>String.prototype.toJSON()</code></li>
<li><code>Boolean.prototype.toJSON()</code></li>
</ul>
<p>The <code>JSON</code> object and these methods in IE5 or IE7 document mode are undefined.</p>
<p><strong>Note:</strong> Even though <code>Date.prototype.toJSON()</code> is supported in IE8 document, <code>Date.prototype.toISOString()</code> is not implemented. This is strange because they return the same value.</p>
<h2>DOM getters/setters</h2>
<p>One of the more curious aspects of the JScript engine is that it implements ECMAScript 5 getters and setters, but <a href="http://msdn.microsoft.com/en-us/library/dd229916%28VS.85%29.aspx">only for DOM objects</a> and not for native JavaScript objects. The implementation is made up of half-baked versions of <code>Object.defineProperty()</code> and <code>Object.getOwnPropertyDescriptor()</code> that primarily support the get and set properties. For example:</p>
<pre><code>Object.defineProperty(document.body, "active", {
    set: function(value){
        document.body.className = (value !== false) ? "active" : "";
    },

    get: function(){
        return document.body.className == "active";
    }

});

var descriptor = Object.getOwnPropertyDescriptor(document.body, "innerHTML");
alert(descriptor.get);   //displays function</code></pre>
<p>Both methods are only available in IE8 document mode and do not exist in other document modes.</p>
<h2>Arrays</h2>
<p>One of the areas where the JScript implementation really fell apart was in dealing with arrays. Arrays had the most deviations from the ECMAScript 3 standard and were a constant source of headaches for developers. First, if undefined is passed into <code>join()</code>, the argument was translated into the string &#8220;undefined&#8221; and that was used to concatenate the items. For example:</p>
<pre><code>var colors = ["red", "green", "blue"];
alert(colors.join(undefined));    //"redundefinedgreenundefinedblue" in IE7</code></pre>
<p>When running in IE8 document mode, a value of <code>undefined</code> is ignored and the default separator (a comma) is used.</p>
<p>The <code>unshift()</code> method, which pushes an item to the front of the array, also had a deviation in JScript. Instead of returning the length of the array after adding the item, it simply returned <code>undefined</code>. In IE8 document mode, this has been fixed so that <code>unshift()</code> correctly returns the array length.</p>
<p>The last big change to arrays is the ability to properly inherit from the <code>Array</code> type. Dean Edwards has a <a href="http://dean.edwards.name/weblog/2006/11/hooray/">whole post</a> about trying to create a subtype of <code>Array</code> and the problems he encountered. The biggest problem is that assigning an instance of <code>Array</code> to be another constructor&#8217;s prototype meant that the <code>length</code> property would no longer work. Consider the following:</p>
<pre><code>function MyArray(){
}

MyArray.prototype = new Array();
MyArray.prototype.get = function(i){
    return this[i];
};

var colors = new MyArray();
colors.push("red");
colors.push("green");
colors.sort();
alert(colors.get(0));    //"green"
alert(colors.length);    //in IE7, outputs "0"; in IE8, outputs "2"</code></pre>
<p>In Internet Explorer prior to 8, the <code>length</code> property of any <code>Array</code> type descendant didn&#8217;t change automatically, and so inheritance was only truly useful only for non-IE browsers. In IE8 document mode, though, the <code>length</code> property works as it does in other browsers while IE5 and IE7 document modes use the old deviated behavior.</p>
<h2>Miscellaneous fixes</h2>
<p>There&#8217;s a small group of fixes that can&#8217;t really be logically categorized but nonetheless help JScript come more into agreement with other JavaScript implementations. The first is that object literals now allow trailing commas. Prior to Internet Explorer 8, the following would cause a parse error:</p>
<pre><code>var object = {
    name: "value",
};</code></pre>
<p>The trailing comma after the last property value is explicitly allowed by ECMAScript 3 syntax and is allowed in all other browsers. IE8 document mode now also supports this syntax correctly (other document modes still throw the error).</p>
<p>Another nice enhancement is that IE8 document mode now allows access to characters in a string via bracket notation:</p>
<pre><code>var s = "Hello world!";
alert(s[0]);    //"H"</code></pre>
<p>This brings JScript into line with other JavaScript engines; IE5 and IE7 document modes will still return <code>undefined</code>.</p>
<p>Two other changes that likely don&#8217;t affect you but are worth noting:</p>
<ul>
<li><code>Number.prototype.toPrecision()</code> used to throw an error when <code>undefined</code> was passed in. IE8 document mode now defaults to calling <code>Number.prototype.toString()</code> in this case.</li>
<li><code>Error.prototype.toString()</code> has been properly implemented to provide better error messages.</li>
</ul>
<h2>Conclusion</h2>
<p>IE8 document mode offers a whole host of improvements over Internet Explorer 7 not just in CSS but also in JavaScript. If you&#8217;re looking to write the most standards-compliant code possible, make sure your page is being run on Internet Explorer 8 in IE8 document mode (see my previous post for details). Bringing JScript into line with other JavaScript engines is an incredibly important step. It&#8217;s too bad that these details were pretty much overlooked in the Internet Explorer 8 announcements.<br />
<h2>Related posts</h2>
<ul class="related_post">
<li><a href="http://www.nczonline.net/blog/2007/09/09/inconsistent-array-literals/" title="Inconsistent array literals">Inconsistent array literals</a></li>
<li><a href="http://www.nczonline.net/blog/2010/01/19/internet-explorer-8-document-and-browser-modes/" title="Internet Explorer 8 document and browser modes">Internet Explorer 8 document and browser modes</a></li>
<li><a href="http://www.nczonline.net/blog/2009/04/04/xpath-in-javascript-part-3/" title="XPath in JavaScript, Part 3">XPath in JavaScript, Part 3</a></li>
<li><a href="http://www.nczonline.net/blog/2009/01/13/speed-up-your-javascript-part-1/" title="Speed up your JavaScript, Part 1">Speed up your JavaScript, Part 1</a></li>
<li><a href="http://www.nczonline.net/blog/2008/09/07/inside-ie-8s-mutable-dom-prototypes/" title="Inside IE 8&#8217;s mutable DOM prototypes">Inside IE 8&#8217;s mutable DOM prototypes</a></li>
<li><a href="http://www.nczonline.net/blog/2008/04/27/cross-domain-xhr-removed-from-firefox-3/" title="Cross-domain XHR removed from Firefox 3">Cross-domain XHR removed from Firefox 3</a></li>
</ul>
<p>P.S. My new book, <a href="http://www.amazon.com/gp/product/059680279X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=059680279X">High Performance JavaScript</a> is coming out in early 2010. Need help now? Check out <a href="http://www.amazon.com/gp/product/047022780X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=047022780X">Professional JavaScript, 2nd Edition</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=Tn7FT-QLK1s:DROfUbh7GXg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=Tn7FT-QLK1s:DROfUbh7GXg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=Tn7FT-QLK1s:DROfUbh7GXg:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=Tn7FT-QLK1s:DROfUbh7GXg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=Tn7FT-QLK1s:DROfUbh7GXg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=Tn7FT-QLK1s:DROfUbh7GXg:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/Tn7FT-QLK1s" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2010/02/02/how-internet-explorer-8-document-mode-affects-javascript/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.nczonline.net/blog/2010/02/02/how-internet-explorer-8-document-mode-affects-javascript/</feedburner:origLink></item>
		<item>
		<title>Answering Baranovskiy’s JavaScript quiz</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/Rwif9skct9k/</link>
		<comments>http://www.nczonline.net/blog/2010/01/26/answering-baranovskiys-javascript-quiz/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 13:00:24 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[Hoisting]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=2385</guid>
		<description><![CDATA[Last week, I tweeted about a JavaScript quiz I came across on Dmitry Baranovskiy’s blog entitled, So you think you know JavaScript? As with other quizzes of this type, there is only one question to answer for five different pieces of example code: what is the result? The example code tests some of the quirkier [...]]]></description>
			<content:encoded><![CDATA[<p>Last week, I <a href="http://twitter.com/slicknet/status/8057003813">tweeted</a> about a JavaScript quiz I came across on Dmitry Baranovskiy’s blog entitled, <a href="http://dmitry.baranovskiy.com/post/91403200">So you think you know JavaScript?</a> As with other quizzes of this type, there is only one question to answer for five different pieces of example code: what is the result? The example code tests some of the quirkier attributes of JavaScript engine behavior. I&#8217;ve seen similar quizzes in the past, sometimes by people saying that they use it as a test during job interviews. I think doing so is both disrespectful to the candidate as well as generally useless. You don&#8217;t encounter this type of quirk every day, so making that the minimum to get a job is about as useful as asking flight attendant candidate to explain jet propulsion.</p>
<p>Still, I liked some of the example code in this post because it can be used to explain some interesting things about JavaScript as a language. The following is an in-depth explanation of what is happening in each of those examples.</p>
<h2>Example #1</h2>
<pre><code>if (!("a" in window)) {
    var a = 1;
}
alert(a);</code></pre>
<p>This strange looking piece of code seems to say, &#8220;if window doesn&#8217;t have a property &#8216;a&#8217;, define a variable &#8216;a&#8217; and assign it the value of 1.&#8221; You would then expect the alert to display the number 1. In reality, the alert displays &#8220;undefined&#8221;. To understand why this happens, you need to know three things about JavaScript.</p>
<p>First, all global variables are properties of <code>window</code>. Writing <code>var a = 1</code> is functionally equivalent to writing <code>window.a = 1</code>. You can check to see if a global variable is declared, therefore, by using the following:</p>
<pre><code>"variable-name" in window</code></pre>
<p>Second, all variable declarations are <em>hoisted</em> to the top of the containing scope. Consider this simpler example:</p>
<pre><code>alert("a" in window);
var a;</code></pre>
<p>The alert in this case outputs &#8220;true&#8221; even though the variable declaration comes after the test. This is because the JavaScript engine first scans for variable declarations and moves them to the top. The engine ends up executing the code like this:</p>
<pre><code>var a;
alert("a" in window);
</code></pre>
<p>Reading this code, it makes far more sense as to why the alert would display &#8220;true&#8221;.</p>
<p>The third thing you need to understand to make sense of this example is that while variable <em>declarations</em> are hoisted, variable <em>initializations</em> are not. This line is both a declaration and an initialization:</p>
<pre><code>var a = 1;</code></pre>
<p>You can separate out the declaration and the initialization like this:</p>
<pre><code>var a;    //declaration
a = 1;    //initialization</code></pre>
<p>When the JavaScript engines comes across a combination of declaration and initialization, it does this split automatically so that the declaration can be hoisted. Why isn&#8217;t the initialization hoisted? Because that could affect the value of the variable during code execution and lead to unexpected results.</p>
<p>So, knowing these three aspects of JavaScript, re-examine the original code. The code actually gets executed as if it were the following:</p>
<pre><code>var a;
if (!("a" in window)) {
    a = 1;
}
alert(a);</code></pre>
<p>Looking at this code should make the solution obvious. The variable <code>a</code> is declared first, and then the <code>if</code> statement says, &#8220;if <code>a</code> isn&#8217;t declared, then initialize <code>a</code> to have a value of 1.&#8221; Of course, this condition can never be true and so the variable a remains with its default value, <code>undefined</code>.</p>
<h2>Example #2</h2>
<pre><code>var a = 1,
    b = function a(x) {
        x &amp;&amp; a(--x);
    };
alert(a);
</code></pre>
<p>This code looks far more complex than it actually is. The result is that the alert displays the number 1, the value to which a was initialized. But why is that? Once again, this example relies on knowledge of three key aspects of JavaScript.</p>
<p>The first concept is that of variable declaration hoisting, which example #1 also relied upon. The second concept is that of <em>function</em> declaration hoisting. All function declarations are hoisted to the top of the containing scope along with variable declarations. Just to be clear, a function declaration looks like this:</p>
<pre><code>function functionName(arg1, arg2){
    //function body
}</code></pre>
<p>This is opposed to a function expression, which is a variable assignment:</p>
<pre><code>var functionName = function(arg1, arg2){
    //function body
};</code></pre>
<p>To be clear, function expressions <em>are not</em> hoisted. This should make sense to you now, as just with variable initialization, moving the assignment of a value from one spot in code to another can alter the execution significantly.</p>
<p>The third concept that you must know to both understand and get confused by this example is that function declarations override variable declarations but not variable initializations. To understand this, consider the following</p>
<pre><code>function value(){
    return 1;
}
</code><code>var value;</code>
<code>alert(typeof value);    //"function"</code></pre>
<p>The variable <code>value</code> ends up as a function even though the variable declaration appears after the function declaration. The function declaration is given priority in this situation. However, throw in variable initialization and you get a different result:</p>
<pre><code>function value(){
    return 1;
}
</code><code>var value = 1;</code>
<code>alert(typeof value);    //"number"</code></pre>
<p>Now the variable <code>value</code> is set to 1. The variable initialization overrides the function declaration.</p>
<p>Back to the example code, the function is actually a function expression despite the name. Named function expressions are not considered function declarations and therefore don&#8217;t get overridden by variable declarations. However, you&#8217;ll note that the variable containing the function expression is <code>b</code> while the function expression&#8217;s name is <code>a</code>. Browsers handle that a differently. Internet Explorer treats it as a function declaration, so it gets overridden by the variable initialization, meaning that the call to <code>a(--x)</code> causes an error. All other browsers allow the call to <code>a(--x)</code> inside of the function while a is still a number outside of the function. Basically, calling <code>b(2)</code> in Internet Explorer throws a JavaScript error but returns <code>undefined</code> in others.</p>
<p>All of that being said, a more correct and easier to understand version of the code would be:</p>
<pre><code>var a = 1,
    b = function(x) {
        x &amp;&amp; b(--x);
    };
alert(a);</code></pre>
<p>Looking at this code, it should be clear that <code>a</code> will always be 1.</p>
<h2>Example #3</h2>
<pre><code>function a(x) {
    return x * 2;
}
var a;
alert(a);
</code></pre>
<p>If you were able to understand the previous example, then this one should be pretty simple. The only thing you need to understand is that function declarations trump variable declarations unless there&#8217;s an initialization. There&#8217;s no initialization here, so the alert displays the source code of the function.</p>
<h2>Example #4</h2>
<pre><code>function b(x, y, a) {
    arguments[2] = 10;
    alert(a);
}
b(1, 2, 3);</code></pre>
<p>This code is a bit easier to understand as the only real question you must answer is whether the alert displays 3 or 10. The answer is 10 in all browsers. There&#8217;s only one concept you need to know to figure out this code. ECMA-262, 3rd Edition, section 10.1.8 says about an <code>arguments</code> object:</p>
<blockquote><p>For each non-negative integer, <code>arg</code>, less than the value of the <code>length</code> property, a property is created with name <code>ToString(arg)</code> and property attributes <code>{ DontEnum }</code>. The initial value of this property is the value of the corresponding actual parameter supplied by the caller. The first actual parameter value corresponds to <code>arg</code> = 0, the second to <code>arg</code> = 1, and so on. In the case when <code>arg</code> is less than the number of formal parameters for the <code>Function</code> object, this property shares its value with the corresponding property of the activation object. <em>This means that changing this property changes the corresponding property of the activation object and vice versa.</em></p></blockquote>
<p>In short, each entry in the <code>arguments</code> object is a duplicate of each named argument. Note that the values are shared, but not the memory space. The two memory spaces are kept synchronized by the JavaScript engine, which means that both <code>arguments[2]</code> and <code>a</code> contain the same value at all times. That value ends up being 10.</p>
<h2>Example #5</h2>
<pre><code>function a() {
    alert(this);
}
a.call(null);
</code></pre>
<p>I actually considered this to be the easiest of the five examples in this quiz. It relies on understanding two JavaScript concepts.</p>
<p>First, you must understand how the value of the <code>this</code> object is determined. When a method is called on an object, <code>this</code> points to the object on which the method resides. Example:</p>
<pre><code>var object = {
    method: function() {
        alert(this === object);    //true
    }
}
object.method(); </code></pre>
<p>In this code, <code>this</code> ends up pointing to <code>object</code> when <code>object.method()</code> is called. In the global scope, <code>this</code> is equivalent to <code>window</code> (in browsers, in non-browser environments it&#8217;s the <code>global</code> object equivalent), so <code>this</code> is also equal to <code>window</code> inside of a function that isn&#8217;t an object property. Example:</p>
<pre><code>function method() {
    alert(this === window);    //true
}
method(); </code></pre>
<p>Here, <code>this</code> ends up pointing to the global object, <code>window</code>.</p>
<p>Armed with this knowledge, you can now tackle the second important concept: what <code>call()</code> does. The <code>call()</code> method executes a function as if it were a method of another object. The first argument becomes <code>this</code> inside the method, and each subsequent argument is passed as an argument to the function. Consider the following:</p>
<pre><code>function method() {
    alert(this === window);
}
method();    //true
method.call(document);   //false</code></pre>
<p>Here, the <code>method()</code> function is called such that <code>this</code> will be <code>document</code>. Therefore, the alert displays &#8220;false&#8221;.</p>
<p>An interesting part of ECMA-262, 3rd edition describes what should happen when <code>null</code> is passed in as the first argument to <code>call()</code>:</p>
<blockquote><p>If <code>thisArg</code> is <code>null</code> or <code>undefined</code>, <em>the called function is passed the global object as the this value</em>. Otherwise, the called function is passed <code>ToObject(thisArg)</code> as the this value.</p></blockquote>
<p>So whenever <code>null</code> is passed to <code>call()</code> (or its sibling, <code>apply()</code>), it defaults to the global object, which is <code>window</code>. Given that, the example code can be rewritten in a more understandable way as:</p>
<pre><code>function a() {
    alert(this);
}
a.call(window);</code></pre>
<p>This code makes it obvious that the alert will be displaying the string equivalent of the <code>window</code> object.</p>
<h2>Conclusion</h2>
<p>Dmitry put together an interesting quiz from which you can actually learn some of the strange quirks of JavaScript. I hope that this writeup has helped everyone understand the details necessary to figure out what each piece of code is doing, and more importantly, why it&#8217;s doing so. Again, I caution against using these sort of quizzes for job interviews as I don&#8217;t think they serve any practical use in that realm (if you&#8217;d like to know my take on interviewing front-end engineers, see my <a href="http://www.nczonline.net/blog/2010/01/05/interviewing-the-front-end-engineer/">previous post</a>).<br />
<h2>Related posts</h2>
<ul class="related_post">
<li><a href="http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/" title="Custom events in JavaScript">Custom events in JavaScript</a></li>
<li><a href="http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/" title="Maintainable JavaScript: Don&#8217;t modify objects you don&#8217;t own">Maintainable JavaScript: Don&#8217;t modify objects you don&#8217;t own</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/23/answering-soshnikovs-quiz/" title="Answering Soshnikov&#8217;s quiz">Answering Soshnikov&#8217;s quiz</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/18/my-javascript-quiz-answers/" title="My JavaScript quiz - answers">My JavaScript quiz - answers</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/16/my-javascript-quiz/" title="My JavaScript quiz">My JavaScript quiz</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/09/announcing-high-performance-javascript/" title="Announcing High Performance JavaScript">Announcing High Performance JavaScript</a></li>
</ul>
<p>P.S. My new book, <a href="http://www.amazon.com/gp/product/059680279X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=059680279X">High Performance JavaScript</a> is coming out in early 2010. Need help now? Check out <a href="http://www.amazon.com/gp/product/047022780X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=047022780X">Professional JavaScript, 2nd Edition</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=Rwif9skct9k:JhmNfea4GjM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=Rwif9skct9k:JhmNfea4GjM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=Rwif9skct9k:JhmNfea4GjM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=Rwif9skct9k:JhmNfea4GjM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=Rwif9skct9k:JhmNfea4GjM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=Rwif9skct9k:JhmNfea4GjM:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/Rwif9skct9k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2010/01/26/answering-baranovskiys-javascript-quiz/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.nczonline.net/blog/2010/01/26/answering-baranovskiys-javascript-quiz/</feedburner:origLink></item>
		<item>
		<title>Internet Explorer 8 document and browser modes</title>
		<link>http://feedproxy.google.com/~r/nczonline/~3/NJSfRUtdbi4/</link>
		<comments>http://www.nczonline.net/blog/2010/01/19/internet-explorer-8-document-and-browser-modes/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 13:00:06 +0000</pubDate>
		<dc:creator>Nicholas C. Zakas</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[Browser Mode]]></category>

		<category><![CDATA[CSS]]></category>

		<category><![CDATA[Document Mode]]></category>

		<category><![CDATA[Internet Explorer]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Quirks Mode]]></category>

		<category><![CDATA[Standards Mode]]></category>

		<guid isPermaLink="false">http://www.nczonline.net/blog/?p=2377</guid>
		<description><![CDATA[When Microsoft began planning for Internet Explorer 8, they were struck with an interesting problem. They were willing to admit that Internet Explorer had implementation bugs both in rendering and scripting. After admitting that, though, they had the problem that is commonly referred to as &#8220;don&#8217;t break the Internet.&#8221; Microsoft had no way of knowing [...]]]></description>
			<content:encoded><![CDATA[<p>When Microsoft began planning for Internet Explorer 8, they were struck with an interesting problem. They were willing to admit that Internet Explorer had implementation bugs both in rendering and scripting. After admitting that, though, they had the problem that is commonly referred to as &#8220;don&#8217;t break the Internet.&#8221; Microsoft had no way of knowing how many sites were reliant upon the implementation bugs to function correctly. Their ultimate solution to the problem was interesting: Internet Explorer 8 could run in a variety of different modes. The sheer number of possible modes is a bit daunting but basically comes down to two types: document mode and browser mode.</p>
<h2>Document mode</h2>
<p>A page&#8217;s document mode determines to which features it has access. This means that there&#8217;s a specific level of CSS support, a specific number of features available for scripting through JavaScript, and a specific way that doctypes are treated. There are three different document modes:</p>
<ul>
<li><strong>Internet Explorer 5</strong> - renders the page in IE7 quirks mode (also known as IE5 mode). New features in IE8 are not available.</li>
<li><strong>Internet Explorer 7</strong> - renders the page in IE7 standards mode.  New features in IE8 are not available.</li>
<li><strong>Internet Explorer 8</strong> - renders the page in IE8 standards mode. New features in IE8 are available, so you can access the Selectors API, more CSS 2 selectors, some CSS 3 features, HTML 5 features, etc. Essentially, you get everything that IE8 has to offer.</li>
</ul>
<p>The concept of document mode is very important for understanding how Internet Explorer 8 works.</p>
<h3>Forcing a document mode</h3>
<p>You can force a particular document mode by using the <code>X-UA-Compatible</code> HTTP header or by using the <code>&lt;meta&gt;</code> tag equivalent:</p>
<pre><code>&lt;meta http-equiv="X-UA-Compatible" content="IE=<em>IEVersion</em>"&gt;</code></pre>
<p>There are several different possible values for the IE version in this field and they don&#8217;t necessary map to the three document modes:</p>
<ul>
<li><strong>Edge</strong> - always put the document into the most recent document mode available. Doctype is ignored. For Internet Explorer 8, this forces the document mode to IE8 standards all the time. Be careful when using this because when Internet Explorer 9 comes out, this will force the page into IE9 standards <strong>mode.</strong></li>
<li><strong>EmulateIE8</strong> - if a doctype is present, set the document mode to IE8 standards and otherwise set the document mode to IE5.</li>
<li><strong>EmulateIE7</strong> - if a doctype is present, set the document mode to IE7 standards and otherwise set the document mode to IE5.</li>
<li><strong>8</strong> - force document mode to be IE8 standards. Doctype is ignored.</li>
<li><strong>7</strong> - force document mode to be IE7 standards. Doctype is ignored.</li>
<li><strong>5</strong> - force document mode to be IE5. Doctype is ignored.</li>
</ul>
<p>For example, to make the document mode behave as it would in Internet Explorer 7, you can use the following:</p>
<pre><code>&lt;meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"&gt;</code></pre>
<p>Whereas to force IE7 standards mode regardless of doctype, use this:</p>
<pre><code>&lt;meta http-equiv="X-UA-Compatible" content="IE=7"&gt;</code></pre>
<p>You are not required to have an <code>X-UA-Compatible</code> field set on pages. If not present, the default is <code>EmulateIE8</code>.</p>
<h3>Detecting document mode</h3>
<p>You can determine the document mode for a given page using the <code>document.documentMode</code> property a new feature in Internet Explorer 8, which returns either 5, 7, or 8:</p>
<pre><code>var mode = document.documentMode;</code></pre>
<p>Using this property can give you a hint as to how the page is going to behave. This property is available in all document modes.</p>
<h2>Browser mode</h2>
<p>There are three browser modes: Internet Explorer 8, Internet Explorer 8 compatibility, and Internet Explorer 7. These modes affect the page in a number of ways, most notably by altering document mode and the user-agent string. By default, the browser mode is set to Internet Explorer 8.</p>
<h3>Internet Explorer 8 mode</h3>
<p>By default, the browser runs in Internet Explorer 8 mode. The document mode is determined as if <code>X-UA-Compatible</code> is set to EmulateIE8. The user-agent string for the browser includes both the Internet Explorer version and the Trident (rendering engine) version. For instance, I see this on my machine:</p>
<pre><code>Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727)</code></pre>
<p>Most pages end up running in Internet Explorer 8 browser mode.</p>
<h3>Internet Explorer 8 compatibility mode</h3>
<p>When an end user clicks the <a href="http://www.microsoft.com/uk/windows/internet-explorer/features/enhanced-navigation.aspx">compatibility view button</a> next to refresh button, the browser mode changes to Internet Explorer 8 compatibility. IE8 compatibility mode is meant to emulate Internet Explorer 7 and so the  document mode is determined as if <code>X-UA-Compatible</code> is set to EmulateIE7. The user-agent string for the browser changes the Internet Explorer version 7 but leaves Trident (rendering engine) version. For instance, I see this on my machine:</p>
<pre><code>Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727)</code></pre>
<p>The user-agent string change is to ensure that any code reliant on user-agent sniffing continues to function as if running in Internet Explorer 7. Leaving the Trident version allows developers the opportunity to determine that this is, in fact, Internet Explorer 8 running in compatibility mode.</p>
<h3>Internet Explorer 7 mode</h3>
<p>Internet Explorer 7 mode is the most curious of all browser modes as it appears to be an option in <a href="http://msdn.microsoft.com/en-us/library/dd565626%28VS.85%29.aspx#browserModeMenu">IE Developer Tools</a> only. The documentation states that this is used to test your site in an actual Internet Explorer 7 instance rather than Internet Explorer 8 running in compatibility mode. Internet Explorer 7 determines the document mode as if <code>X-UA-Compatible</code> is set to EmulateIE7. Additionally, this mode completely disregards <code>X-UA-Compatible</code> and so there is no way to manually change the document mode (Internet Explorer 7 didn&#8217;t honor <code>X-UA-Compatible</code> either). This means that unlike the other browser modes, Internet Explorer 7 mode can never have a document mode of IE8 standards. Further, the user-agent string is changes so that the Trident version is no longer available. Here it is on my box:</p>
<pre><code>Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)</code></pre>
<p>There doesn&#8217;t appear to be any other way that and end user can trigger Internet Explorer 7 mode. As such, it appears that this is just a convenience tool for developers that frees us from needing to  and so it appears to be a tool used primary for developers</p>
<h2>Summary</h2>
<p>Internet Explorer 8 has some powerful, and confusing, features as it relates to its rendering and execution engine. Document modes are used to determine which features are available to the page, and that includes which CSS features and which JavaScript features are enabled and available. You can tell the browser how you would like the document mode to be determined by specifying a value of <code>X-UA-Compatible</code>.</p>
<p>Browser modes change how the document mode is determined when <code>X-UA-Compatible</code> is not specified. They also change the user-agent string so that user-agent sniffers won&#8217;t be broken. In the wild, you will only see Internet Explorer 8 mode and Internet Explorer 8 compatibility mode; Internet Explorer 7 mode appears to be just for developer usage.<br />
<h2>Related posts</h2>
<ul class="related_post">
<li><a href="http://www.nczonline.net/blog/2008/03/09/ie8-goodies-and-baddies/" title="IE8 goodies and baddies">IE8 goodies and baddies</a></li>
<li><a href="http://www.nczonline.net/blog/2010/02/02/how-internet-explorer-8-document-mode-affects-javascript/" title="How Internet Explorer 8 document mode affects JavaScript">How Internet Explorer 8 document mode affects JavaScript</a></li>
<li><a href="http://www.nczonline.net/blog/2009/12/15/writing-maintainable-code/" title="Writing maintainable code">Writing maintainable code</a></li>
<li><a href="http://www.nczonline.net/blog/2009/04/04/xpath-in-javascript-part-3/" title="XPath in JavaScript, Part 3">XPath in JavaScript, Part 3</a></li>
<li><a href="http://www.nczonline.net/blog/2008/09/07/inside-ie-8s-mutable-dom-prototypes/" title="Inside IE 8&#8217;s mutable DOM prototypes">Inside IE 8&#8217;s mutable DOM prototypes</a></li>
<li><a href="http://www.nczonline.net/blog/2008/04/27/cross-domain-xhr-removed-from-firefox-3/" title="Cross-domain XHR removed from Firefox 3">Cross-domain XHR removed from Firefox 3</a></li>
</ul>
<p>P.S. My new book, <a href="http://www.amazon.com/gp/product/059680279X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=059680279X">High Performance JavaScript</a> is coming out in early 2010. Need help now? Check out <a href="http://www.amazon.com/gp/product/047022780X?ie=UTF8&tag=nczonline-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=047022780X">Professional JavaScript, 2nd Edition</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nczonline?a=NJSfRUtdbi4:nhKHsQZHU38:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nczonline?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=NJSfRUtdbi4:nhKHsQZHU38:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nczonline?i=NJSfRUtdbi4:nhKHsQZHU38:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=NJSfRUtdbi4:nhKHsQZHU38:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nczonline?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nczonline?a=NJSfRUtdbi4:nhKHsQZHU38:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nczonline?i=NJSfRUtdbi4:nhKHsQZHU38:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nczonline/~4/NJSfRUtdbi4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.nczonline.net/blog/2010/01/19/internet-explorer-8-document-and-browser-modes/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.nczonline.net/blog/2010/01/19/internet-explorer-8-document-and-browser-modes/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic Page Served (once) in 1.690 seconds --><!-- Cached page generated by WP-Super-Cache on 2010-03-17 05:33:50 --><!-- Compression = gzip -->
