<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CkUERHszeip7ImA9WhBaFE8.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627</id><updated>2013-05-24T20:30:05.582+02:00</updated><category term="flash" /><category term="latex" /><category term="free" /><category term="community" /><category term="textbook" /><category term="hosting" /><category term="meta-data" /><category term="nature" /><category term="adobe" /><category term="regexp" /><category term="12quirks" /><category term="lion" /><category term="thunderbolt" /><category term="chrome" /><category term="jsengine" /><category term="dzone" /><category term="audio" /><category term="git" /><category term="jslang" /><category term="light peak" /><category term="michael j. fox" /><category term="bookmarklet" /><category term="video" /><category term="sponsoring" /><category term="jshistory" /><category term="blink" /><category term="googleio" /><category term="facebook" /><category term="java" /><category term="talk" /><category term="hci" /><category term="ical" /><category term="jsshell" /><category term="philosophy" /><category term="computers" /><category term="vlc" /><category term="pdf" /><category term="app urls" /><category term="obama" /><category term="read" /><category term="theora" /><category term="german" /><category term="opinion" /><category term="mac" /><category term="dsl" /><category term="marketing" /><category term="design" /><category term="airbender" /><category term="blogging" /><category term="coffeescript" /><category term="google" /><category term="education" /><category term="futurama" /><category term="scitech" /><category term="deutsch" /><category term="month" /><category term="eval" /><category term="gadget" /><category term="fringe" /><category term="mssurface" /><category term="openoffice" /><category term="distributed-social-network" /><category term="esnext" /><category term="hyena" /><category term="typography" /><category term="guice" /><category term="webkit" /><category term="nokia" /><category term="ios" /><category term="markdown" /><category term="shell" /><category term="leopard" /><category term="biology" /><category term="steve jobs" /><category term="macbook" /><category term="nodejs" /><category term="gimp" /><category term="fluentconf" /><category term="async" /><category term="canada" /><category term="basic income" /><category term="hardware" /><category term="hack" /><category term="math" /><category term="english" /><category term="usb" /><category term="aol" /><category term="howto" /><category term="repl" /><category term="music" /><category term="diaspora" /><category term="firefly" /><category term="raspberry pi" /><category term="publishing" /><category term="icloud" /><category term="jquery" /><category term="energy" /><category term="angry birds" /><category term="nike" /><category term="unix" /><category term="webos" /><category term="twitter" /><category term="angularjs" /><category term="webapp" /><category term="numbers" /><category term="health" /><category term="emberjs" /><category term="mobile" /><category term="webm" /><category term="mpaa" /><category term="astronomy" /><category term="html5" /><category term="web" /><category term="jstools" /><category term="mars" /><category term="gwt" /><category term="comic" /><category term="flattr" /><category term="polymer" /><category term="puzzle" /><category term="jsmyth" /><category term="middle east" /><category term="dvd" /><category term="occupy" /><category term="library" /><category term="firefox" /><category term="location" /><category term="psychology" /><category term="iphone" /><category term="travel" /><category term="css" /><category term="netflix" /><category term="society" /><category term="software engineering" /><category term="app" /><category term="v8" /><category term="tv" /><category term="eclipse" /><category term="star trek" /><category term="webdev" /><category term="facets" /><category term="safari" /><category term="humor" /><category term="winphone" /><category term="home entertainment" /><category term="business" /><category term="meego" /><category term="lightning" /><category term="tizen" /><category term="security" /><category term="semantic web" /><category term="ted" /><category term="cloud" /><category term="servo" /><category term="gaming" /><category term="tmplstr" /><category term="oracle" /><category term="info mgmt" /><category term="scifi-fantasy" /><category term="movie" /><category term="windows 8" /><category term="photo" /><category term="android" /><category term="chromeos" /><category term="presenting" /><category term="amdefine" /><category term="intel" /><category term="software" /><category term="html" /><category term="dev" /><category term="fun" /><category term="crowdsourcing" /><category term="architecture" /><category term="rust" /><category term="itunes" /><category term="journalism" /><category term="hp" /><category term="web design" /><category term="yahoo" /><category term="media" /><category term="app store" /><category term="münchen" /><category term="pl fundamentals" /><category term="webcomponents" /><category term="javascript" /><category term="2ality" /><category term="firefoxos" /><category term="apple" /><category term="tablet" /><category term="ipad" /><category term="environment" /><category term="social" /><category term="underscorejs" /><category term="organizing" /><category term="tc39" /><category term="pixar" /><category term="dart" /><category term="feedback" /><category term="python" /><category term="amazon" /><category term="browser" /><category term="ecommerce" /><category term="layout" /><category term="facetator" /><category term="motorola" /><category term="programming languages" /><category term="thunderbird" /><category term="linux" /><category term="javafx" /><category term="jsmodules" /><category term="idea" /><category term="emacs" /><category term="guide" /><category term="law" /><category term="jslib" /><category term="internet explorer" /><category term="programming" /><category term="politics" /><category term="raffle" /><category term="back to the future" /><category term="jsdom" /><category term="htc" /><category term="wwdc" /><category term="h.264" /><category term="__proto__" /><category term="book" /><category term="samsung" /><category term="googleplus" /><category term="jsfuture" /><category term="sponsor" /><category term="cross-platform" /><category term="life" /><category term="kindle" /><category term="fritzbox" /><category term="bluetooth" /><category term="blogger" /><category term="jsstyle" /><category term="voice control" /><category term="food" /><category term="entertainment" /><category term="history" /><category term="house" /><category term="microsoft" /><category term="foreign languages" /><category term="mozilla" /><category term="series" /><category term="traffic" /><category term="clientjs" /><category term="msl" /><title>②ality – JavaScript and more</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.2ality.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.2ality.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>914</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/2ality" /><feedburner:info uri="2ality" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CEYBQ309fCp7ImA9WhBaE0w.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-5616060225593284215</id><published>2013-05-23T14:10:00.001+02:00</published><updated>2013-05-23T14:29:12.364+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-23T14:29:12.364+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="webcomponents" /><category scheme="http://www.blogger.com/atom/ns#" term="angularjs" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="polymer" /><category scheme="http://www.blogger.com/atom/ns#" term="emberjs" /><category scheme="http://www.blogger.com/atom/ns#" term="webdev" /><title>Plans for supporting Web Components in AngularJS and Ember.js</title><content type="html">Web Components &lt;a class="ptr"&gt;[1]&lt;/a&gt; are an upcoming standard for custom HTML5 user interface elements. Those UI elements will eventually become interchangeable between frameworks. Now the people behind AngularJS and Ember.js have described their plans for supporting Web Components.
&lt;a name='more'&gt;&lt;/a&gt;
&lt;p&gt;
Below, you’ll see mentions of Google’s new framework, Polymer &lt;a class="ptr"&gt;[1]&lt;/a&gt;. It is built directly on top of Web Components. One of Polymer’s goals is to help refine and fully figure out that standard.

&lt;h3&gt;AngularJS&lt;/h3&gt;

In an &lt;a href="https://groups.google.com/d/msg/polymer-dev/4RSYaKmbtEk/uYnY3900wpIJ"&gt;entry&lt;/a&gt; on Google Groups, AngularJS co-creator Miško Hevery writes:
&lt;blockquote&gt;
We're in early stages of designing Angular 2.0, but some of our goals are:
&lt;ul&gt;
&lt;li&gt;Angular will use the underlying web platform features available to it (e.g. Node.bind, template integration, Custom Elements, etc...)&lt;/li&gt;
&lt;li&gt;Web Components (Polymer, Ember, or any other framework/library) will work seamlessly within Angular apps and directives.&lt;/li&gt;
&lt;li&gt;Components written in Angular will export to Web Components (to be used by Polymer, Ember, or any other framework/library).&lt;/li&gt;
&lt;/ul&gt;
We're working actively with the MDV, Web Components, and Polymer teams to make sure that our approaches remain compatible as all these projects evolve (and they will still evolve).
&lt;/blockquote&gt;

&lt;h3&gt;Ember.js&lt;/h3&gt;

Yehuda Katz, one of Ember‘s creators, has written a Gist with the title “&lt;a href="https://gist.github.com/wycats/9144666b0c606d1838be"&gt;Ember and Web Components&lt;/a&gt;”:
&lt;blockquote&gt;
The goal of this document is to describe how Ember could adopt semantics similar to web components and MDV. It relies on the HTMLBars templating engine, which allows Ember to directly control how templates are parsed and converted into DOM. [&lt;a href="https://github.com/tildeio/htmlbars"&gt;HTMLBars&lt;/a&gt; uses the same Handlebar syntax as current Ember, but compiles it to code that constructs DOM nodes instead of code that concatenates strings. That leads to the above mentioned increase in control.]
&lt;p&gt;
It builds on the work of Rafael Weinstein and the Polymer team, and attempts to harmonize that work with Ember's architecture.
&lt;p&gt;
Ember's scope is much wider than components, and is mostly focused on application architecture and URL-driven design. Today, we need a system to manage the lifecycle of data-binding and custom views, so we include such a system alongside our architectural tools.
&lt;p&gt;
Once the web provides its own tools for managing components, and eventually data bindings, Ember will embrace them and transition away from our Ember-specific solution. This document is how we get from here to there, continuing to build ambitious and stable applications in the meantime.
&lt;p&gt;
[...]
&lt;/blockquote&gt;
The document is a great primer on how Web Components differ from Ember.

&lt;h3&gt;Reference&lt;/h3&gt;

&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/05/google-polymer.html"&gt;Google’s Polymer and the future of web UI frameworks&lt;/a&gt;
        [describes both Web Components and Polymer]
    &lt;/li&gt;
&lt;/ol&gt;
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/TuKuFE60neE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/5616060225593284215/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=5616060225593284215" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/5616060225593284215?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/5616060225593284215?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/TuKuFE60neE/web-components-angular-ember.html" title="Plans for supporting Web Components in AngularJS and Ember.js" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.2ality.com/2013/05/web-components-angular-ember.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8ARnY8eyp7ImA9WhBaE00.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-8245472080614673477</id><published>2013-05-23T11:46:00.000+02:00</published><updated>2013-05-23T12:10:47.873+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-23T12:10:47.873+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="12quirks" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="jslang" /><title>JavaScript quirk 7: inadvertent sharing of variables via closures</title><content type="html">[This post is part of a &lt;a href="http://www.2ality.com/2013/04/12quirks.html"&gt;series&lt;/a&gt; on JavaScript quirks.]
&lt;p&gt;
Closures are a powerful JavaScript feature: If a function leaves the place where it was created, it still has access to all variables that existed at that place. This blog post explains how closures work and why one has to be careful w.r.t. inadvertent sharing of variables.

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h3 class="countheads"&gt;Closures&lt;/h3&gt;

Let’s start with an example of a closure:
&lt;pre&gt;
    function incrementorFactory(start, step) {
        return function () {  // (*)
            start += step;
            return start;
        }
    }
&lt;/pre&gt;
This is how you use &lt;tt&gt;incrementorFactory&lt;/tt&gt;:
&lt;pre&gt;
    &amp;gt; var inc = incrementorFactory(20, 2);
    &amp;gt; inc()
    22
    &amp;gt; inc()
    24
&lt;/pre&gt;
During all of its lifetime, the inner function (*) has access to the variables &lt;tt&gt;start&lt;/tt&gt; and &lt;tt&gt;step&lt;/tt&gt; of the outer function &lt;tt&gt;incrementorFactory&lt;/tt&gt;. Thus, &lt;tt&gt;incrementorFactory&lt;/tt&gt; returns not only the function, but somehow attaches the variables &lt;tt&gt;start&lt;/tt&gt; and &lt;tt&gt;step&lt;/tt&gt;. The data structure in which both variables are stored is called an &lt;tt&gt;environment&lt;/tt&gt;. An environment is very similar to an object – it maps names to values. The function that is returned above contains a reference to the environment that was active at its birth, its &lt;i&gt;outer environment&lt;/i&gt;. The combination function + environment is called a &lt;i&gt;closure&lt;/i&gt;. The name stems from the fact that an environment “closes over” a function: It provides values for variables that were declared outside the function (so-called &lt;i&gt;free variables&lt;/i&gt;).
&lt;p&gt;
When a function &lt;tt&gt;f&lt;/tt&gt; is invoked, a new environment is created for its parameters and local variables. There is always a chain of environments:
&lt;ul&gt;
    &lt;li&gt;&lt;tt&gt;f&lt;/tt&gt;’s environment&lt;/li&gt;
    &lt;li&gt;&lt;tt&gt;f&lt;/tt&gt;’s outer environment&lt;/li&gt;
    &lt;li&gt;The outer environment of &lt;tt&gt;f&lt;/tt&gt;’s outer environment&lt;/li&gt;
    &lt;li&gt;...&lt;/li&gt;
    &lt;li&gt;The environment for global variables (the &lt;i&gt;global environment&lt;/i&gt;)&lt;/li&gt;
&lt;/ul&gt;
When looking up the value of a variable, the complete chain is searched, starting with &lt;tt&gt;f&lt;/tt&gt;’s environment.

&lt;h3&gt;The quirk: inadvertent sharing&lt;/h3&gt;

Closures don’t get snapshots of a certain point in time, they get “live” variables. The following is an example where that causes a problem.
&lt;pre&gt;
    var result = [];
    for (var i=0; i &amp;lt; 5; i++) {
        result.push(function () { return i });  // (*)
    }
    console.log(result[3]()); // 5 (not 3)
&lt;/pre&gt;
When a function is created in line (*), the variable &lt;tt&gt;i&lt;/tt&gt; has a certain value. You might expect that function to always return that value.
Instead, the connection to the “live” &lt;tt&gt;i&lt;/tt&gt; is never broken.
That is, all functions in the array &lt;tt&gt;result&lt;/tt&gt; share the same &lt;tt&gt;i&lt;/tt&gt;, via their outer environment.
And after the loop is finished, &lt;tt&gt;i&lt;/tt&gt; has the value &lt;tt&gt;5&lt;/tt&gt;.
&lt;p&gt;
One possible fix is to copy the current value of &lt;tt&gt;i&lt;/tt&gt; via an IIFE &lt;a class="ptr"&gt;[1]&lt;/a&gt;:
&lt;pre&gt;
    for (var i=0; i &amp;lt; 5; i++) {
        (function (i2) {  // snaphot of i
            result.push(function () { return i2 });
        }(i));
    }
&lt;/pre&gt;
You can also use &lt;a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind"&gt;&lt;tt&gt;bind()&lt;/tt&gt;&lt;/a&gt;, with a similar effect:
&lt;pre&gt;
    for (var i=0; i &amp;lt; 5; i++) {
        result.push(function (i2) { return i2 }.bind(null, i));
    }
&lt;/pre&gt;
Another possibility is using &lt;tt&gt;forEach&lt;/tt&gt; and the &lt;a href="http://underscorejs.org/#range"&gt;&lt;tt&gt;range()&lt;/tt&gt;&lt;/a&gt; function of the Underscore.js library:
&lt;pre&gt;
    _.range(5).forEach(function (i) {
        result.push(function () { return i });
    });
&lt;/pre&gt;
The above works, because &lt;tt&gt;forEach&lt;/tt&gt; creates a new variable &lt;tt&gt;i&lt;/tt&gt;, each time it calls its argument.

&lt;h4&gt;A practical example&lt;/h4&gt;

Let’s conclude with a more practical example. Two days ago, I implemented a user interface for the game &lt;a href="http://en.wikipedia.org/wiki/Connect_Four"&gt;Connect Four&lt;/a&gt;, as a demonstration of the DOM. It contained the following code snippet, which adds event listeners to links above the columns of the board.
&lt;pre&gt;
    for(var col=0; col &amp;lt; board4.DIM_X; col++) {
        document.getElementById('columnClick'+col)
                .addEventListener('click', function (col) {
                    currentState.columnClick(col);
                    event.preventDefault();
                }.bind(null, col));
    }
&lt;/pre&gt;
An alternative is to use CSS classes instead of IDs and rewrite the above code:
&lt;pre&gt;
    Array.prototype.forEach.call(
        document.getElementsByClassName('columnClick'),
        function (elem, col) {  // (*)
            elem.addEventListener('click', function () {
                currentState.columnClick(col);
                event.preventDefault();
            });
        });
&lt;/pre&gt;
Again, each invocation of the function (*) creates a new variable &lt;tt&gt;col&lt;/tt&gt; and no inadvertent sharing occurs.
&lt;p&gt;
The last post in this series will explain how ECMAScript 6 helps with the problem of inadvertent sharing.

&lt;h3&gt;Reference&lt;/h3&gt;

&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/05/quirk-variable-scope.html"&gt;JavaScript quirk 6: the scope of variables&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/GF5br1VCIDs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/8245472080614673477/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=8245472080614673477" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/8245472080614673477?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/8245472080614673477?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/GF5br1VCIDs/quirk-closures.html" title="JavaScript quirk 7: inadvertent sharing of variables via closures" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.2ality.com/2013/05/quirk-closures.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QER3c9fip7ImA9WhBaE0w.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-357872070228110549</id><published>2013-05-18T14:17:00.000+02:00</published><updated>2013-05-23T14:15:06.966+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-23T14:15:06.966+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="webcomponents" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="polymer" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><category scheme="http://www.blogger.com/atom/ns#" term="webdev" /><title>Google’s Polymer and the future of web UI frameworks</title><content type="html">&lt;b&gt;Update 2013-05-23:&lt;/b&gt;
&lt;a href="http://www.2ality.com/2013/05/web-components-angular-ember.html"&gt;Plans for supporting Web Components in AngularJS and Ember.js&lt;/a&gt;
&lt;p&gt;
At Google I/O 2013, Google presented a new web user interface (UI) framework called &lt;a href="http://www.polymer-project.org/"&gt;Polymer&lt;/a&gt;. The way it works is indicative of the future of all web UI frameworks.

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h3 class="countheads"&gt;Polymer&lt;/h3&gt;

Polymer is composed of the following layers:
&lt;ul&gt;
    &lt;li&gt;Foundation (platform.js): Foundational building blocks. Most, if not all, of these APIs will eventually become native browser APIs.
    &lt;/li&gt;
    &lt;li&gt;Core (polymer.js): Helpers complementing Foundation.
    &lt;/li&gt;
    &lt;li&gt;Elements: UI and non-UI components built on Core.
    &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;The Foundation layer (platform.js)&lt;/h4&gt;

The Foundation layer comprises the following technologies:
&lt;ol&gt;
    &lt;li&gt;&lt;a href="http://dom.spec.whatwg.org/#mutation-observers"&gt;DOM Mutation Oberservers&lt;/a&gt; and &lt;a href="http://updates.html5rocks.com/2012/11/Respond-to-change-with-Object-observe"&gt;Object.observe()&lt;/a&gt; (probably ECMAScript 7): for observing changes to DOM elements and plain JavaScript objects.
    &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.polymer-project.org/platform/pointer-events.html"&gt;Pointer Events&lt;/a&gt;: handle mouse and touch in the same manner, on all platforms.
    &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.polymer-project.org/platform/shadow-dom.html"&gt;Shadow DOM&lt;/a&gt;: encapsulate structure and style inside elements (e.g. custom ones).
    &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.polymer-project.org/platform/custom-elements.html"&gt;Custom Elements&lt;/a&gt;: define your own HTML5 elements. The names of custom elements must contain a dash, which is a simple way of namespacing them and distinguishes them from standard elements.
    &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.polymer-project.org/platform/html-imports.html"&gt;HTML Imports&lt;/a&gt;: package custom elements. Such packages include HTML, CSS and JavaScript.
    &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.polymer-project.org/platform/mdv.html"&gt;Model-Driven Views (MDV)&lt;/a&gt;: Does data-binding directly in HTML. Not yet in the process of being standardized.
    &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.polymer-project.org/platform/web-animations.html"&gt;Web Animations&lt;/a&gt;: API unifying several of the web’s animation approaches.
    &lt;/li&gt;
&lt;/ol&gt;
APIs 3–5 are part of &lt;a href="http://www.w3.org/TR/components-intro/"&gt;Web Components&lt;/a&gt;, a component model for the web. Web components are the most important foundation of Polymer.
&lt;p&gt;
platform.js shims these APIs on browsers where they are not (yet) available. It is only 31KB (if minified and gzipped). One of the declared goals of Polymer is to field-test HTML5 UI APIs before standardizing them.

&lt;h4&gt;Layers: Core and Elements&lt;/h4&gt;

Polymer itself is almost like native HTML5: “attributes in, events out”. One example of using the UI widget &lt;tt&gt;polymer-panels&lt;/tt&gt;:
&lt;pre&gt;
    &amp;lt;polymer-panels
        on-select="panelSelectHandler"
        selected="{{selectedPanelIndex}}"&amp;gt;
    &amp;lt;/polymer-panels&amp;gt;
&lt;/pre&gt;
Its architecture is very component-oriented, its components being HTML elements. Some of the elements don’t even have a user interfaces themselves. For example, animations are elements (you can nest them etc.), they have no user interface, but instead point to UI elements that they animate. Responsive design is built into many widgets, which means that they will transform so that they work best on a given platform (cell phone, tablet, desktop, etc.).

&lt;h4&gt;Interoperability&lt;/h4&gt;

Polymer is designed to be à la carte: you pick and choose what you need. Thanks to Web Components, its elements are also highly interoperable. In one demo given at I/O, an element coming from the Mozilla project &lt;a href="http://www.x-tags.org"&gt;X-Tag&lt;/a&gt; (that is similarly based on Web Components) was shown as working inside Polymer.

&lt;h4&gt;When can I use it?&lt;/h4&gt;

Polymer is still pre-alpha and thus not yet really ready for public consumption. It is, however, developed in the open and you can already play with &lt;a href="http://www.polymer-project.org/getting-the-code.html"&gt;its code&lt;/a&gt;.

&lt;h4&gt;Polymer versus other frameworks&lt;/h4&gt;

Polymer is not the framework to end all other frameworks. Instead, existing frameworks can be based on the same foundations. In fact, the functionality of most of the APIs that were mentioned above should look familiar to you if you have already used a UI framework such as Ember.js or AngularJS. As for AngularJS, a recent &lt;a href="https://twitter.com/angularjs/status/335417160438542337"&gt;tweet&lt;/a&gt; explains how it will evolve:
&lt;blockquote&gt;
    AngularJS will use Polymer for its widgets. It's win-win.
&lt;/blockquote&gt;

&lt;h3&gt;What does it all mean?&lt;/h3&gt;

Nobody actually wants to use frameworks. We only want to build web user interfaces efficiently and frameworks help. The most important pieces missing from native HTML are:
&lt;ul&gt;
    &lt;li&gt;A rich set of widgets. In my opinion, this is the biggest deal about Web Components (and, to a lesser degree, about Polymer). We finally get a large set of widgets that we can use anywhere.
    &lt;/li&gt;
    &lt;li&gt;User interface layout. I have high hopes for &lt;a href="http://www.w3.org/TR/css3-grid-layout/"&gt;CSS Grid Layout&lt;/a&gt; here. Grid Layout is native HTML, so it complements Web Components quite naturally.
    &lt;/li&gt;
    &lt;li&gt;“Glue” to combine widgets (e.g. data binding).
    &lt;/li&gt;
&lt;/ul&gt;
Currently, frameworks are largely incompatible: they usually come with their own tool chain, inheritance API, widget infrastructure, etc.
The developments described in this post, along with ECMAScript 6’s &lt;a href="http://www.2ality.com/2012/07/esnext-classes.html"&gt;classes&lt;/a&gt; and modules, point to a future where everything will be much more interoperable. The benefits for the web development ecosystem are obvious.

&lt;h3&gt;Resources&lt;/h3&gt;

If you want to know more about Web Components and Polymer, you have the following resources at your disposal:
&lt;ul&gt;
    &lt;li&gt;Talks at Google I/O 2013:
        &lt;ul&gt;
            &lt;li&gt;“&lt;a href="https://developers.google.com/events/io/sessions/318907648"&gt;Web Components: A Tectonic Shift for Web Development&lt;/a&gt;” by Eric Bidelman
            &lt;/li&gt;
            &lt;li&gt;“&lt;a href="https://developers.google.com/events/io/sessions/324149970"&gt;Web Components in Action&lt;/a&gt;” by Matthew McNulty, Alex Komoroske [builds on the previous talk, covers Polymer]
            &lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.html5rocks.com/en/tutorials/#webcomponents"&gt;HTML5 Rocks&lt;/a&gt;: articles on Web Components.
    &lt;/li&gt;
    &lt;li&gt;Polymer homepage: &lt;a href="http://polymer-project.org/"&gt;polymer-project.org&lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/pngbcRWybh4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/357872070228110549/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=357872070228110549" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/357872070228110549?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/357872070228110549?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/pngbcRWybh4/google-polymer.html" title="Google’s Polymer and the future of web UI frameworks" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://www.2ality.com/2013/05/google-polymer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0INQ3oyfip7ImA9WhBbGEw.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-4012411509973400351</id><published>2013-05-15T20:33:00.001+02:00</published><updated>2013-05-17T19:26:32.496+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-17T19:26:32.496+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="12quirks" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="jslang" /><title>JavaScript quirk 6: the scope of variables</title><content type="html">[This post is part of a &lt;a href="http://www.2ality.com/2013/04/12quirks.html"&gt;series&lt;/a&gt; on JavaScript quirks.]

&lt;p&gt;
In most programming languages, variables only exist within the block in which they have been declared. In JavaScript, they exist in the complete (innermost) surrounding function:
&lt;pre&gt;
    function func(x) {
        console.log(tmp); // undefined
        if (x &amp;lt; 0) {
            var tmp = 100 - x;  // (*)
            ...
        }
    }
&lt;/pre&gt;

&lt;a name='more'&gt;&lt;/a&gt;

The cause of the above behavior is &lt;i&gt;hoisting&lt;/i&gt;: Internally, the declaration at (*) is moved to the beginning of the function (the assignment stays where it is). That is, what a JavaScript engine actually executes looks like this:
&lt;pre&gt;
    function func(x) {
        var tmp;
        console.log(tmp); // undefined
        if (x &amp;lt; 0) {
            tmp = 100 - x;
            ...
        }
    }
&lt;/pre&gt;
But there is a trick to limit the scope of a variable to a block, it is called &lt;i&gt;Immediately Invoked Function Expression&lt;/i&gt; (IIFE, pronounced “iffy”). Below, we use an IIFE to restrict the scope of &lt;tt&gt;tmp&lt;/tt&gt; to the then-block of the &lt;tt&gt;if&lt;/tt&gt; statement.
&lt;pre&gt;
    function func(x) {
        console.log(tmp); // ReferenceError: tmp is not defined
        if (x &amp;lt; 0) {
            (function () {  // open IIFE
                var tmp = 100 - x;
                ...
            }());  // close IIFE
        }
    }
&lt;/pre&gt;
We wrapped a function around the insides of the block, creating a new scope for them. Then we immediately called that function. &lt;tt&gt;tmp&lt;/tt&gt; only exists inside the IIFE. Note that the parentheses at the beginning and the end of the IIFE are necessary. They lead to the function being interpreted as an expression, which is the only form in which it can be be immediately invoked.
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/d3ZfLnuTMu4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/4012411509973400351/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=4012411509973400351" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/4012411509973400351?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/4012411509973400351?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/d3ZfLnuTMu4/quirk-variable-scope.html" title="JavaScript quirk 6: the scope of variables" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.2ality.com/2013/05/quirk-variable-scope.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUEGQn49eyp7ImA9WhBbFUk.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-4831206976839179129</id><published>2013-05-14T17:00:00.000+02:00</published><updated>2013-05-14T17:00:23.063+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-14T17:00:23.063+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="computers" /><category scheme="http://www.blogger.com/atom/ns#" term="life" /><category scheme="http://www.blogger.com/atom/ns#" term="netflix" /><category scheme="http://www.blogger.com/atom/ns#" term="business" /><title>Netflix’s technology and hiring practices</title><content type="html">In the article “&lt;a href="http://www.businessweek.com/articles/2013-05-09/netflix-reed-hastings-survive-missteps-to-join-silicon-valleys-elite"&gt;Netflix, Reed Hastings Survive Missteps to Join Silicon Valley's Elite&lt;/a&gt;”, Ashlee Vance profiles Netflix and its CEO Hastings for Businessweek. The article mentions a few interesting tidbits about the company’s technology and hiring practices:
&lt;a name='more'&gt;&lt;/a&gt;
&lt;ul&gt;
    &lt;li&gt;Netflix data comprises a third of the incoming data in North American homes.&lt;/li&gt;
    &lt;li&gt;Their infrastructure is based on Amazon Web Services.&lt;/li&gt;
    &lt;li&gt;In off-peak hours, Netflix’s systems are repurposed to analyze data. The results are used to pre-cache data and to determine the likelihood of success of a show that Netflix might finance.
    &lt;/li&gt;
    &lt;li&gt;As an employer, Netflix pays well:
        &lt;blockquote&gt;
            Managers routinely survey salary trends in Silicon Valley and pay their employees 10 percent to 20 percent more than the going rate for a given skill. Fired employees also get ultragenerous severance packages; the idea is to remove guilt as an obstacle to management parting ways with subpar performers.
        &lt;/blockquote&gt;
        And they prefer to have older employees:
        &lt;blockquote&gt;
            Netflix also tends to employ older people than its peers. “We hire fully formed adults,” says Cockcroft. “We let them do five years at Google before taking them on.” 
        &lt;/blockquote&gt;
    &lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/xIFYyCJUa10" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/4831206976839179129/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=4831206976839179129" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/4831206976839179129?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/4831206976839179129?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/xIFYyCJUa10/netflix.html" title="Netflix’s technology and hiring practices" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.2ality.com/2013/05/netflix.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MDQXY9fyp7ImA9WhBbE00.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-1677362257695151374</id><published>2013-05-11T22:51:00.001+02:00</published><updated>2013-05-11T22:51:10.867+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-11T22:51:10.867+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="jslang" /><category scheme="http://www.blogger.com/atom/ns#" term="jshistory" /><title>JavaScript history: undefined</title><content type="html">Two tweets by Brendan Eich shed light on the history of JavaScript having both &lt;tt&gt;undefined&lt;/tt&gt; and &lt;tt&gt;null&lt;/tt&gt; &lt;a class="ptr"&gt;[1]&lt;/a&gt;.

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;
The first version of JavaScript did not have exception handling, which is why JavaScript so often converts automatically &lt;a class="ptr"&gt;[2]&lt;/a&gt; and/or fails silently (&lt;a href="https://twitter.com/BrendanEich/status/333008305461006336"&gt;tweet&lt;/a&gt;).
&lt;p&gt;
JavaScript copied Java’s approach of partitioning values into primitives and objects &lt;a class="ptr"&gt;[3]&lt;/a&gt;. &lt;tt&gt;null&lt;/tt&gt; is the value for “not an object”. The precedent from C (but not from Java) is to convert &lt;tt&gt;null&lt;/tt&gt; to 0 (C has pointers, not references and lets you perform &lt;a href="http://en.wikipedia.org/wiki/Pointer_(computer_programming)#C_arrays"&gt;arithmetic&lt;/a&gt; with pointers).
&lt;p&gt;
Remaining problem: In JavaScript, each variable can hold both primitives and objects. In Java, a variable’s static type limits it to either kind of value. We therefore need a value for “neither a primitive nor an object”. That value could be &lt;tt&gt;null&lt;/tt&gt;, but at the time, Eich wanted something that wasn’t “reference-y” (associated with objects) and did not convert to 0 (&lt;a href="https://twitter.com/BrendanEich/status/330775086208524288"&gt;tweet&lt;/a&gt;). Now you know why &lt;tt&gt;undefined&lt;/tt&gt; and &lt;tt&gt;null&lt;/tt&gt; are converted to different numbers:
&lt;pre&gt;
    &amp;gt; Number(undefined)
    NaN
    &amp;gt; Number(null)
    0
&lt;/pre&gt;
&lt;p&gt;
&lt;b&gt;References:&lt;/b&gt;
&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/04/quirk-undefined.html"&gt;JavaScript quirk 2: two “non-values” – undefined and null&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/04/quirk-implicit-conversion.html"&gt;JavaScript quirk 1: implicit conversion of values&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/01/categorizing-values.html"&gt;Categorizing values in JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/uLXrkzOE8ng" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/1677362257695151374/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=1677362257695151374" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/1677362257695151374?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/1677362257695151374?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/uLXrkzOE8ng/history-undefined.html" title="JavaScript history: undefined" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.2ality.com/2013/05/history-undefined.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIGQ3Y5fSp7ImA9WhBbEk8.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-6073779525637060138</id><published>2013-05-10T22:48:00.000+02:00</published><updated>2013-05-10T23:15:22.825+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-10T23:15:22.825+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mobile" /><category scheme="http://www.blogger.com/atom/ns#" term="scitech" /><title>Beyond “always on”</title><content type="html">Current technology encourages us to be continuously connected. This blog post predicts that that will change.

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h3&gt;Always on&lt;/h3&gt;

The direction that technology currently takes us could be described as “always on”. The goal is to give us more updates, more quickly. Three recent examples. First, &lt;a href="https://www.facebook.com/home"&gt;Facebook Home&lt;/a&gt;. The website describes the “always on” vision quite well (emphasis is mine):
&lt;blockquote&gt;
    With Home, everything on your phone gets friendlier. From the moment you turn it on, you see a steady stream of friends’ posts and photos. Upfront notifications and quick access to your essentials mean &lt;b&gt;you’ll never miss a moment&lt;/b&gt;. And you can keep chatting with friends, even when you’re using other apps.
&lt;/blockquote&gt;
Second, &lt;a href="http://www.google.com/glass/start/"&gt;Google Glass&lt;/a&gt;, where there is always a screen in front of your eyes. Third, existing and rumored smart watches which are also about receiving notifications more directly.

&lt;h3&gt;Beyond “always on”&lt;/h3&gt;

Notifications are a form of stimuli. And, for evolutionary-biological reasons, those are hard to resist for humans. They are mental sugar, if you will. However, we need periods of rest. Thus, my prediction is that health concerns and decreasing interest in social media (et al.) will eventually lead people to look for alternatives.
Historically, communication has (roughly) gone through the following stages:
&lt;ul&gt;
    &lt;li&gt;very sporadic and asynchronous (letters)&lt;/li&gt;
    &lt;li&gt;sporadic and synchronous (traditional phones)&lt;/li&gt;
    &lt;li&gt;sporadic and asynchronous (non-mobile email)&lt;/li&gt;
    &lt;li&gt;continuous and synchronous (mobile dumbphones)&lt;/li&gt;
    &lt;li&gt;continuous and asynchronous, with the occasional synchronous communication (mobile smartphones)&lt;/li&gt;
&lt;/ul&gt;
The most important technology for giving us freedom from “always on” is (fast) asynchronous communication. As we are moving away from being continuously connected, I expect many innovations in that area. Managing one’s attention is a competitive advantage, which increases the likelihood of good solutions being created – there is money to be made.
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/4PD-Zu1SeBY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/6073779525637060138/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=6073779525637060138" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/6073779525637060138?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/6073779525637060138?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/4PD-Zu1SeBY/beyond-always-on.html" title="Beyond “always on”" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.2ality.com/2013/05/beyond-always-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQFSXY9fip7ImA9WhBbEE4.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-4866751346392367905</id><published>2013-05-08T05:35:00.001+02:00</published><updated>2013-05-08T18:25:18.866+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-08T18:25:18.866+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="photo" /><category scheme="http://www.blogger.com/atom/ns#" term="nature" /><category scheme="http://www.blogger.com/atom/ns#" term="fun" /><category scheme="http://www.blogger.com/atom/ns#" term="life" /><title>Pets in wheelchairs</title><content type="html">Cute: two pets lost their ability to use their hind legs, so their owners built them wheelchairs.
&lt;a name='more'&gt;&lt;/a&gt;
&lt;p&gt;
First: the piglet “&lt;a href="http://www.thesun.co.uk/sol/homepage/features/4774519/Pig-in-a-wheelchair.html"&gt;Chris P. Bacon&lt;/a&gt;”.
&lt;p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-r4vGqk_-x9A/UYnHUMhnBGI/AAAAAAAAAvo/j2KeiYDGxWA/s1600/piglet.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="253" src="http://2.bp.blogspot.com/-r4vGqk_-x9A/UYnHUMhnBGI/AAAAAAAAAvo/j2KeiYDGxWA/s400/piglet.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;
Second: the kitten “&lt;a href="http://www.peoplepets.com/people/pets/article/0,,20696694,00.html"&gt;Brigitta&lt;/a&gt;”.
&lt;p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-uvl2VPsolb4/UYnHUKnwlWI/AAAAAAAAAvw/d0RksuY-MwU/s1600/kitten.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="http://1.bp.blogspot.com/-uvl2VPsolb4/UYnHUKnwlWI/AAAAAAAAAvw/d0RksuY-MwU/s400/kitten.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/XQ54ChtUkyM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/4866751346392367905/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=4866751346392367905" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/4866751346392367905?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/4866751346392367905?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/XQ54ChtUkyM/pets-in-wheelchairs.html" title="Pets in wheelchairs" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-r4vGqk_-x9A/UYnHUMhnBGI/AAAAAAAAAvo/j2KeiYDGxWA/s72-c/piglet.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.2ality.com/2013/05/pets-in-wheelchairs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYAQno8fyp7ImA9WhBUF04.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-137330939732378405</id><published>2013-05-05T09:15:00.000+02:00</published><updated>2013-05-05T09:15:43.477+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-05T09:15:43.477+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="12quirks" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="jslang" /><title>JavaScript quirk 5: parameter handling</title><content type="html">[This post is part of a &lt;a href="http://www.2ality.com/2013/04/12quirks.html"&gt;series&lt;/a&gt; on JavaScript quirks.]
&lt;p&gt;
The basics of parameter handling in JavaScript are simple, advanced tasks require manual work. This blog post first looks at the basics and then covers advanced topics.

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h3 class="countheads"&gt;The basics of parameter handling&lt;/h3&gt;

Two facts form the core of JavaScript parameter handling.

&lt;h4&gt;Fact: you can always pass an arbitrary amount of parameters&lt;/h4&gt;

When calling a function, you can pass as many or as few actual parameters as you want, independently of how many formal parameters are mentioned in the function declaration. Parameters that are missing have the value &lt;tt&gt;undefined&lt;/tt&gt;. Parameters that are too many are ignored. Let’s use the following function for a demonstration:
&lt;pre&gt;
    function f(x, y) {
        console.log('x: '+x);
        console.log('y: '+y);
    }
&lt;/pre&gt;
You can call this function with arbitrary many parameters:
&lt;pre&gt;
    &amp;gt; f()
    x: undefined
    y: undefined

    &amp;gt; f('a')
    x: a
    y: undefined

    &amp;gt; f('a', 'b')
    x: a
    y: b

    &amp;gt; f('a', 'b', 'c')
    x: a
    y: b
&lt;/pre&gt;

&lt;h4&gt;Fact: all passed parameters are stored in &lt;tt&gt;arguments&lt;/tt&gt;&lt;/h4&gt;

All passed parameters are stored in the special, “Array-like” (see below for what that means) variable &lt;tt&gt;arguments&lt;/tt&gt;. The following function lets us examine how that variable works.
&lt;pre&gt;
    function g() {
        console.log('Length: '+arguments.length);
        console.log('Elements: '+fromArray(arguments));
    }
&lt;/pre&gt;
Function &lt;tt&gt;fromArray&lt;/tt&gt; is shown below, it converts &lt;tt&gt;arguments&lt;/tt&gt; to an array so that it can be logged. Using &lt;tt&gt;g()&lt;/tt&gt;:
&lt;pre&gt;
    &gt; g()
    Length: 0
    Elements: 
    &gt; g('a')
    Length: 1
    Elements: a
    &gt; g('a', 'b')
    Length: 2
    Elements: a,b
&lt;/pre&gt;
&lt;tt&gt;arguments&lt;/tt&gt; is always there, no matter how many parameters have been explicitly declared. It always contains all actual parameters.

&lt;h3&gt;Has a parameter been passed?&lt;/h3&gt;

If a caller does not provide a parameter, &lt;tt&gt;undefined&lt;/tt&gt; is passed to the function. Because &lt;tt&gt;undefined&lt;/tt&gt; is falsy &lt;a class="ptr"&gt;[1]&lt;/a&gt;, you can use an &lt;tt&gt;if&lt;/tt&gt; statement to check whether the parameter “exists” or not:
&lt;pre&gt;
    function hasParameter(param) {
        if (param) {
            return 'yes';
        } else {
            return 'no';
        }
    }
&lt;/pre&gt;
Thus, you get the same result if you omit a parameter and if you pass &lt;tt&gt;undefined&lt;/tt&gt;:
&lt;pre&gt;
    &amp;gt; hasParameter()
    'no'
    &amp;gt; hasParameter(undefined)
    'no'
&lt;/pre&gt;
The test works also well for truthy values:
&lt;pre&gt;
    &amp;gt; hasParameter([ 'a', 'b' ])
    'yes'
    &amp;gt; hasParameter({ name: 'Jane' })
    'yes'
    &amp;gt; hasParameter('Hello')
    'yes'
&lt;/pre&gt;
With falsy values, however, you have to be careful. For example, &lt;tt&gt;false&lt;/tt&gt;, zero and the empty string are interpreted as missing parameters:
&lt;pre&gt;
    &amp;gt; hasParameter(false)
    'no'
    &amp;gt; hasParameter(0)
    'no'
    &amp;gt; hasParameter('')
    'no'
&lt;/pre&gt;
Still, this pattern has proven itself. You do have to be vigilant, but the code becomes pleasantly compact and it does not matter whether callers omit a parameter, pass &lt;tt&gt;undefined&lt;/tt&gt; or pass &lt;tt&gt;null&lt;/tt&gt;.

&lt;h3&gt;Default values for parameters&lt;/h3&gt;

The following function should accept zero or more parameters. Parameters &lt;tt&gt;x&lt;/tt&gt; and &lt;tt&gt;y&lt;/tt&gt; should have the value &lt;tt&gt;0&lt;/tt&gt; if they are missing. A simple way of doing that is:
&lt;pre&gt;
    function add(x, y) {
        if (!x) x = 0;
        if (!y) y = 0;
        return x + y;
    }
&lt;/pre&gt;
Interaction:
&lt;pre&gt;
    &amp;gt; add()
    0
    &amp;gt; add(5)
    5
    &amp;gt; add(2, 7)
    9
&lt;/pre&gt;
You can write &lt;tt&gt;add()&lt;/tt&gt; more compactly by using the “or” operator (&lt;tt&gt;||&lt;/tt&gt;). This operator returns the first operand if it is truthy and otherwise the second operand. Examples:
&lt;pre&gt;
    &amp;gt; 'abc' || 'def'
    'abc'
    &amp;gt; '' || 'def'
    'def'
    &amp;gt; undefined || { foo: 123 }
    { foo: 123 }
    &amp;gt; { foo: 123 } || 'def'
    { foo: 123 }
&lt;/pre&gt;
Let’s use &lt;tt&gt;||&lt;/tt&gt; to assign parameter default values:
&lt;pre&gt;
    function add(x, y) {
        x = x || 0;
        y = y || 0;
        return x + y;
    }
&lt;/pre&gt;

&lt;h3&gt;An arbitrary number of parameters&lt;/h3&gt;

You can also use &lt;tt&gt;arguments&lt;/tt&gt; to accept an arbitrary number of parameters. One example is the following function &lt;tt&gt;format()&lt;/tt&gt; that is modeled after the classic C function &lt;tt&gt;sprintf&lt;/tt&gt;:
&lt;pre&gt;
    &amp;gt; format('Hello %s! You have %s new message(s).', 'Jane', 5)
    'Hello Jane! You have 5 new message(s).'
&lt;/pre&gt;
The first argument is a pattern in which '%s' marks blanks. The following arguments are filled into those blanks. A simple implementation of &lt;tt&gt;format&lt;/tt&gt; looks like this:
&lt;pre&gt;
    function format(pattern) {
        for(var i=1; i &amp;lt; arguments.length; i++) {
            pattern = pattern.replace('%s', arguments[i]);
        }
        return pattern;
    }
&lt;/pre&gt;
Note: the loop skips the first parameter (&lt;tt&gt;arguments[0]&lt;/tt&gt;) and thus ignores &lt;tt&gt;pattern&lt;/tt&gt;.

&lt;h3&gt;Enforcing a certain number of parameters&lt;/h3&gt;

If you want to force a caller to provide a certain number of parameters, you need to check &lt;tt&gt;arguments.length&lt;/tt&gt;, at runtime:
&lt;pre&gt;
    function add(x, y) {
        if (arguments.length &amp;gt; 2) {
            throw new Error('Need at most 2 parameters');
        }
        return x + y;
    }
&lt;/pre&gt;

&lt;h3&gt;&lt;tt&gt;arguments&lt;/tt&gt; is not an array&lt;/h3&gt;

&lt;tt&gt;arguments&lt;/tt&gt; is not an array, it is only &lt;i&gt;array-like&lt;/i&gt;: you can access the &lt;tt&gt;i&lt;/tt&gt;-th parameter via &lt;tt&gt;arguments[i]&lt;/tt&gt; and you can determine how many parameters there are via &lt;tt&gt;arguments.length&lt;/tt&gt;. But you can’t use &lt;tt&gt;Array&lt;/tt&gt; methods such as &lt;tt&gt;forEach&lt;/tt&gt; and &lt;tt&gt;indexOf&lt;/tt&gt;. Further details, along with solutions are discussed in quirk 8. As a preview, the following function converts an array-like value to an array.
&lt;pre&gt;
    function fromArray(arrayLikeValue) {
        return Array.prototype.slice.call(arrayLikeValue);
    }
&lt;/pre&gt;

&lt;h3&gt;Reference&lt;/h3&gt;

&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/04/quirk-implicit-conversion.html"&gt;JavaScript quirk 1: implicit conversion of values&lt;/a&gt; [explains “truthy” and “falsy”]&lt;/li&gt;
&lt;/ol&gt;
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/h4DS6JY4Uio" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/137330939732378405/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=137330939732378405" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/137330939732378405?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/137330939732378405?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/h4DS6JY4Uio/quirk-parameters.html" title="JavaScript quirk 5: parameter handling" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.2ality.com/2013/05/quirk-parameters.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcER3s9fyp7ImA9WhBUFUQ.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-6278994786197163056</id><published>2013-04-30T09:54:00.000+02:00</published><updated>2013-05-03T16:40:06.567+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-03T16:40:06.567+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="2ality" /><category scheme="http://www.blogger.com/atom/ns#" term="fluentconf" /><category scheme="http://www.blogger.com/atom/ns#" term="raffle" /><title>Win a ticket for Fluent Conference</title><content type="html">&lt;b&gt;Update 2013-05-03:&lt;/b&gt; A winner has been determined and received the ticket.
&lt;p&gt;
&lt;a href="http://fluentconf.com/fluent2013?cmp=mp-code-fl13-2ality-promo"&gt;Fluent Conference&lt;/a&gt; takes place in San Francisco from May 28–30, 2013. Its tag line is “JavaScript &amp;amp; Beyond”. The 2ality blog raffles off a ticket for the last two days (excluding the workshop day).
To win, tweet the following text:
&lt;blockquote&gt;
&lt;pre&gt;
I’d like to win a ticket for Fluent Conference. #2alityFluent
http://www.2ality.com/2013/04/fluent-raffle.html
&lt;/pre&gt;
&lt;/blockquote&gt;
The deadline is Friday, May 3rd, 2013, 14:00 GMT. I’ll contact the winner via Twitter, within a few hours of the deadline. (If the winner isn’t following &lt;a href="http://twitter.com/rauschma"&gt;me&lt;/a&gt; already, I’ll ask them to temporarily do so, so that I can send them a direct message.)
&lt;p&gt;
[Legal disclaimer: I make no guarantees w.r.t. to there being a winner. Contesting this raffle via legal means is not allowed.]
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/ZtfhTfGq9QE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/6278994786197163056/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=6278994786197163056" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/6278994786197163056?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/6278994786197163056?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/ZtfhTfGq9QE/fluent-raffle.html" title="Win a ticket for Fluent Conference" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.2ality.com/2013/04/fluent-raffle.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUAQ344fip7ImA9WhBUEkw.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-2194241385470224443</id><published>2013-04-28T15:58:00.004+02:00</published><updated>2013-04-29T08:17:22.036+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-29T08:17:22.036+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="12quirks" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="jslang" /><title>JavaScript quirk 4: unknown variable names create global variables</title><content type="html">[This post is part of a &lt;a href="http://www.2ality.com/2013/04/12quirks.html"&gt;series&lt;/a&gt; on JavaScript quirks.]
&lt;p&gt;
Normally, JavaScript automatically creates a global variable if you use an unknown variable name:
&lt;pre&gt;
    &amp;gt; function f() { foo = 123 }
    &amp;gt; f()
    &amp;gt; foo
    123
&lt;/pre&gt;
Thankfully, you get a warning in ECMAScript 5 strict mode &lt;a class="ptr"&gt;[1]&lt;/a&gt;:
&lt;pre&gt;
    &amp;gt; function f() { 'use strict'; foo = 123 }
    &amp;gt; f()
    ReferenceError: foo is not defined
&lt;/pre&gt;
&lt;b&gt;Reference:&lt;/b&gt;
&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2011/01/javascripts-strict-mode-summary.html"&gt;JavaScript’s strict mode: a summary&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/l-ecCAxKCAw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/2194241385470224443/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=2194241385470224443" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/2194241385470224443?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/2194241385470224443?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/l-ecCAxKCAw/quirk-automatic-globals.html" title="JavaScript quirk 4: unknown variable names create global variables" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.2ality.com/2013/04/quirk-automatic-globals.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEYARn0zeyp7ImA9WhBVGEk.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-959054531363810994</id><published>2013-04-24T19:31:00.004+02:00</published><updated>2013-04-25T00:22:27.383+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-25T00:22:27.383+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="12quirks" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="jslang" /><title>JavaScript quirk 3: normal equality (==)</title><content type="html">[This post is part of a &lt;a href="http://www.2ality.com/2013/04/12quirks.html"&gt;series&lt;/a&gt; on JavaScript quirks.]
&lt;p&gt;
Let’s start with a simple rule: the normal equality operators &lt;tt&gt;==&lt;/tt&gt; and &lt;tt&gt;!=&lt;/tt&gt; are so problematic that you should always use strict equality (&lt;tt&gt;===&lt;/tt&gt; and &lt;tt&gt;!==&lt;/tt&gt;). Some people say that there are exceptions to this rule, I disagree &lt;a class="ptr"&gt;[2]&lt;/a&gt;. Keeping this rule in mind, we can now take a look at what is strange about &lt;tt&gt;==&lt;/tt&gt; without burdening our minds unnecessarily.

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;
The “normal” equality operator (&lt;tt&gt;==&lt;/tt&gt;) has many quirks. While it is forgiving, it does not adhere to the typical rules of truthy and falsy (see &lt;a href="http://www.2ality.com/2013/04/quirk-implicit-conversion.html"&gt;quirk 1&lt;/a&gt;):
&lt;pre&gt;
    &amp;gt; 0 == false  // OK
    true
    &amp;gt; 1 == true  // OK
    true
    &amp;gt; 2 == true  // not OK
    false

    &amp;gt; '' == false  // OK
    true
    &amp;gt; '1' == true  // OK
    true
    &amp;gt; '2' == true  // not OK
    false
&lt;/pre&gt;
Apart from that, it lets you compare values that aren’t really comparable:
&lt;pre&gt;
    &amp;gt; '' == 0
    true
    &amp;gt; '\n  123  \t' == 123
    true
&lt;/pre&gt;
The last check is true because conversion to number ignores leading and trailing whitespace in JavaScript.
&lt;p&gt;
If you are still interested in finding out how exactly &lt;tt&gt;==&lt;/tt&gt; works, you can read up on it here: &lt;a class="ptr"&gt;[1]&lt;/a&gt;.
With strict equality (&lt;tt&gt;===&lt;/tt&gt;), values of different types are never equal &lt;a class="ptr"&gt;[1]&lt;/a&gt;, which means that all of the above problems go away.
&lt;p&gt;
&lt;b&gt;References:&lt;/b&gt;
&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2011/06/javascript-equality.html"&gt;Equality in JavaScript: === versus ==&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2011/12/strict-equality-exemptions.html"&gt;When is it OK to use == in JavaScript?&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/Z_L3tVACn5M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/959054531363810994/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=959054531363810994" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/959054531363810994?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/959054531363810994?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/Z_L3tVACn5M/quirk-equality.html" title="JavaScript quirk 3: normal equality (==)" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.2ality.com/2013/04/quirk-equality.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUADRXk5fyp7ImA9WhBVE0U.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-8128824786139856611</id><published>2013-04-19T17:02:00.003+02:00</published><updated>2013-04-19T17:02:54.727+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-19T17:02:54.727+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="jslang" /><title>Checking for undefined: === versus typeof versus falsiness</title><content type="html">There are several ways of checking whether a variable has the value &lt;tt&gt;undefined&lt;/tt&gt;. This blog post explains the differences.

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h3 class="countheads"&gt;Checking via ===&lt;/h3&gt;

Using strict equality &lt;a class="ptr"&gt;[1]&lt;/a&gt; is the canonical way of checking for &lt;tt&gt;undefined&lt;/tt&gt;:
&lt;pre&gt;
    if (x === undefined) ...
&lt;/pre&gt;

&lt;h4&gt;Changing undefined&lt;/h4&gt;

&lt;tt&gt;undefined&lt;/tt&gt; is a &lt;a href="http://ecma-international.org/ecma-262/5.1/#sec-15.1.1.3"&gt;property of the global object&lt;/a&gt; (and thus a global variable). Under ECMAScript 3, you could change its value. Under ECMAScript 5, you can’t do that, any more:
&lt;pre&gt;
    &amp;gt; undefined = 123
    &amp;gt; undefined
    undefined
&lt;/pre&gt;
You can, however, shadow it in a function, either via a parameter or via a local variable:
&lt;pre&gt;
    &amp;gt; (function () { var undefined = 123; return undefined; }())
    123
&lt;/pre&gt;
From now on, &lt;tt&gt;undefined&lt;/tt&gt; is used to refer to the identifier, while &lt;b&gt;undefined&lt;/b&gt; is used to refer to the actual value.
&lt;p&gt;
Because you could globally change the value of &lt;tt&gt;undefined&lt;/tt&gt; under ECMAScript 3, two techniques were often used to ensure that it had the correct value. If you are targeting older browsers, these techniques are still relevant.
&lt;p&gt;
&lt;b&gt;Technique 1:&lt;/b&gt; shadow &lt;tt&gt;undefined&lt;/tt&gt; yourself.
&lt;pre&gt;
    (function (undefined) {
        if (x === undefined) ...  // safe now
    }());  // don’t hand in a parameter
&lt;/pre&gt;
Above, &lt;tt&gt;undefined&lt;/tt&gt; is a parameter whose value is &lt;b&gt;undefined&lt;/b&gt;, because it has not been provided by the caller.
&lt;p&gt;
&lt;b&gt;Technique 2:&lt;/b&gt; compare with &lt;tt&gt;void 0&lt;/tt&gt;. The &lt;tt&gt;void&lt;/tt&gt; operator &lt;a class="ptr"&gt;[2]&lt;/a&gt; evaluates its operand, ignores the result and returns &lt;b&gt;undefined&lt;/b&gt;. That means that &lt;tt&gt;void 0&lt;/tt&gt; will always evaluate to &lt;b&gt;undefined&lt;/b&gt;.
&lt;pre&gt;
    if (x === void 0)  // always safe
&lt;/pre&gt;

&lt;h3&gt;Checking via typeof&lt;/h3&gt;

You can also check for &lt;tt&gt;undefined&lt;/tt&gt; via the &lt;tt&gt;typeof&lt;/tt&gt; operator &lt;a class="ptr"&gt;[3]&lt;/a&gt;:
&lt;pre&gt;
    if (typeof x === 'undefined') ...
&lt;/pre&gt;

This is more verbose and can be slower (though many engines optimize). It has two advantages: First, it is safe with regard to a changed &lt;tt&gt;undefined&lt;/tt&gt; (not that important under ECMAScript 5). Second, it also works for unknown variables:
&lt;pre&gt;
    &amp;gt; typeof iDontKnowThisVariable === 'undefined'
    true
    &amp;gt; iDontKnowThisVariable === undefined
    ReferenceError: iDontKnowThisVariable is not defined
&lt;/pre&gt;

&lt;h3&gt;Checking for falsiness&lt;/h3&gt;

&lt;b&gt;undefined&lt;/b&gt; is &lt;i&gt;falsy&lt;/i&gt; (interpreted as false in boolean contexts, &lt;a class="ptr"&gt;[4]&lt;/a&gt;):
&lt;pre&gt;
    &amp;gt; Boolean(undefined)
    false
&lt;/pre&gt;
Hence, you can check for &lt;tt&gt;undefined&lt;/tt&gt; like this:
&lt;pre&gt;
    if (!x) ...
&lt;/pre&gt;
The usual caveat applies: The condition of the above if statement will also be true for: &lt;tt&gt;null&lt;/tt&gt;, &lt;tt&gt;false&lt;/tt&gt;, &lt;tt&gt;-0&lt;/tt&gt;, &lt;tt&gt;+0&lt;/tt&gt;, &lt;tt&gt;NaN&lt;/tt&gt;, &lt;tt&gt;""&lt;/tt&gt;.

&lt;h3&gt;Conclusion&lt;/h3&gt;

Recommendation: check for &lt;b&gt;undefined&lt;/b&gt; either via &lt;tt&gt;=== undefined&lt;/tt&gt; or via falsiness. It is normally more important for code to be easy to understand than to be completely safe. Therefore, checking via &lt;tt&gt;=== void 0&lt;/tt&gt; is rarely a good choice.

&lt;h3&gt;References&lt;/h3&gt;

&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2011/06/javascript-equality.html"&gt;Equality in JavaScript: === versus ==&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2011/05/void-operator.html"&gt;The void operator in JavaScript&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/01/categorizing-values.html"&gt;Categorizing values in JavaScript&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/04/quirk-implicit-conversion.html"&gt;JavaScript quirk 1: implicit conversion of values&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/JtCLQDHm1vk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/8128824786139856611/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=8128824786139856611" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/8128824786139856611?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/8128824786139856611?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/JtCLQDHm1vk/check-undefined.html" title="Checking for undefined: === versus typeof versus falsiness" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>7</thr:total><feedburner:origLink>http://www.2ality.com/2013/04/check-undefined.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQBRnYyeSp7ImA9WhBVEkU.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-5826041858866817310</id><published>2013-04-18T14:03:00.003+02:00</published><updated>2013-04-18T14:15:57.891+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-18T14:15:57.891+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="life" /><category scheme="http://www.blogger.com/atom/ns#" term="media" /><title>News is bad for you</title><content type="html">Quoting “&lt;a href="http://www.guardian.co.uk/media/2013/apr/12/news-is-bad-rolf-dobelli"&gt;News is bad for you – and giving up reading it will make you happier&lt;/a&gt;” (by Rolf Dobelli for The Guardian):
&lt;blockquote&gt;
In the past few decades, the fortunate among us have recognised the hazards of living with an overabundance of food (obesity, diabetes) and have started to change our diets. But most of us do not yet understand that news is to the mind what sugar is to the body. News is easy to digest. The media feeds us small bites of trivial matter, tidbits that don't really concern our lives and don't require thinking.
&lt;/blockquote&gt;

&lt;a name='more'&gt;&lt;/a&gt;

This has been on my mind for a long time: Most of the stuff you learn via the news is just as relevant for your actual life as, for example, the politics of &lt;a href="http://en.wikipedia.org/wiki/World_of_A_Song_of_Ice_and_Fire#Westeros"&gt;Westeros&lt;/a&gt;. It’s too far away to matter, a single incident (that we can’t help but generalize), too limited a perspective (a single person writing about a general issue), etc. The uselessness of that knowledge can be easily demonstrated by looking at a newspaper from a year ago: how much of its content is still worth knowing today?
&lt;p&gt;
Furthermore, for biological reasons, negative things more easily attract our attention than positive things, which is why the former make up most of the news. But that skews our perception. To balance it, we would also need to know about people who are currently incredibly happy.
&lt;p&gt;
I don’t advocate ignoring news completely, but you should limit your exposure. It is not my only news source, but I find that Twitter filters the news quite nicely for me; there is a focus on creativity and fun.
But I only follow a few, carefully selected people and try to avoid tweeters that complain too much.
&lt;p&gt;
For pop culture and society news, I’d love to see more positive reporting: highlighting creativity and encouraging multi-facted thinking, as opposed to “fashion fail” negativity and simplistic “she betrayed him” drama.
&lt;p&gt;
So, the next time you feel smug about knowing something about global politics (etc.) that someone else doesn’t – remember: you may only know simple factoids, that may not even be that useful.
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/jVE62AQICQ8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/5826041858866817310/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=5826041858866817310" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/5826041858866817310?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/5826041858866817310?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/jVE62AQICQ8/news-is-bad.html" title="News is bad for you" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.2ality.com/2013/04/news-is-bad.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYARnw_cSp7ImA9WhBWGUo.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-1099656709878879770</id><published>2013-04-14T23:48:00.000+02:00</published><updated>2013-04-15T00:05:47.249+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-15T00:05:47.249+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="12quirks" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="jslang" /><title>JavaScript quirk 2: two “non-values” – undefined and null</title><content type="html">[This post is part of a &lt;a href="http://www.2ality.com/2013/04/12quirks.html"&gt;series&lt;/a&gt; on JavaScript quirks.]
&lt;p&gt;
Most programming languages have only one value for “no value” or “empty reference”. For example, that value is &lt;tt&gt;null&lt;/tt&gt; in Java. JavaScript has two of those special values: &lt;tt&gt;undefined&lt;/tt&gt; and &lt;tt&gt;null&lt;/tt&gt;. They are basically the same (something that will change with ECMAScript 6, as will be explained in the last post of this series), but they are used slightly differently.

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;
&lt;tt&gt;undefined&lt;/tt&gt; is assigned via the language itself. Variables that have not been initialized yet have this value:
&lt;pre&gt;
    &amp;gt; var foo;
    &amp;gt; foo
    undefined
&lt;/pre&gt;
Similarly, JavaScript assigns &lt;tt&gt;undefined&lt;/tt&gt; to missing parameters:
&lt;pre&gt;
    &amp;gt; function id(x) { return x }
    &amp;gt; id()
    undefined
&lt;/pre&gt;
&lt;tt&gt;null&lt;/tt&gt; is used by programmers to explicitly indicate that a value is missing. E.g. for &lt;a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/stringify"&gt;&lt;tt&gt;JSON.stringify()&lt;/tt&gt;&lt;/a&gt;:
&lt;pre&gt;
    &amp;gt; console.log(JSON.stringify({ first: 'Jane' }, null, 4))
    {
        "first": "Jane"
    }
&lt;/pre&gt;

&lt;h3&gt;Check: does a variable have a value?&lt;/h3&gt;

If you want to know whether a variable &lt;tt&gt;v&lt;/tt&gt; has a value, you normally have to check for both &lt;tt&gt;undefined&lt;/tt&gt; and &lt;tt&gt;null&lt;/tt&gt;. Fortunately, both values are &lt;a href="http://www.2ality.com/2013/04/quirk-implicit-conversion.html"&gt;falsy&lt;/a&gt;. Thus, checking for truthiness via &lt;tt&gt;if&lt;/tt&gt; performs both checks at the same time:
&lt;pre&gt;
    if (v) {
        // v has a value
    } else {
        // v does not have a value
    }
&lt;/pre&gt;
You’ll see more examples of the above check in the post for quirk 5 about parameter handling.
There is one caveat: this check also interprets &lt;tt&gt;false&lt;/tt&gt;, &lt;tt&gt;-0&lt;/tt&gt;, &lt;tt&gt;+0&lt;/tt&gt;, &lt;tt&gt;NaN&lt;/tt&gt; and &lt;tt&gt;''&lt;/tt&gt; as “no value”. If that isn’t what you want then you can’t use it. You have two choices.
&lt;p&gt;
Some people advocate lenient non-equality (&lt;tt&gt;!=&lt;/tt&gt;) to check that &lt;tt&gt;v&lt;/tt&gt; is neither &lt;tt&gt;undefined&lt;/tt&gt; nor &lt;tt&gt;null&lt;/tt&gt;:
&lt;pre&gt;
    if (v != null) {
        // v has a value
    } else {
        // v does not have a value
    }
&lt;/pre&gt;
However, that requires you to know that &lt;tt&gt;!=&lt;/tt&gt; considers &lt;tt&gt;null&lt;/tt&gt; to be only equal to itself and to &lt;tt&gt;undefined&lt;/tt&gt;. I prefer the more descriptive use of &lt;tt&gt;!==&lt;/tt&gt;:
&lt;pre&gt;
    if (v !== undefined &amp;amp;&amp;amp; v !== null) {
        // v has a value
    } else {
        // v does not have a value
    }
&lt;/pre&gt;
&lt;a href="http://jsperf.com/definedness"&gt;Performance-wise&lt;/a&gt;, all three checks shown in this section are more or less the same. Hence, which one you will end up using depends on your needs and your taste. Some minification tools even rewrite the last check to a check via &lt;tt&gt;!=&lt;/tt&gt;.&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/Aj0HDk_-s90" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/1099656709878879770/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=1099656709878879770" title="15 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/1099656709878879770?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/1099656709878879770?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/Aj0HDk_-s90/quirk-undefined.html" title="JavaScript quirk 2: two “non-values” – undefined and null" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>15</thr:total><feedburner:origLink>http://www.2ality.com/2013/04/quirk-undefined.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MHQXkzeip7ImA9WhBWFEg.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-7670201567390370726</id><published>2013-04-09T00:02:00.002+02:00</published><updated>2013-04-09T00:17:10.782+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-09T00:17:10.782+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="2ality" /><category scheme="http://www.blogger.com/atom/ns#" term="sponsor" /><title>[Sponsor] Where are JavaScript and the web going?</title><content type="html">&lt;p&gt;&lt;b&gt;The Fluent conference co-chairs look ahead.&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;[A blog post by Simon St. Laurent, &lt;a href="http://programming.oreilly.com/2013/04/where-are-javascript-and-the-web-going.html" rel="nofollow"&gt;originally published&lt;/a&gt; on the O'Reilly Programming Blog, republished with permission.]
&lt;/p&gt;

&lt;p&gt;JavaScript and HTML5 just keep moving.  One day it’s form validation, the next animation. Then it becomes full-on model view controller stacks getting data from sensors on devices and communicating with back-end servers that are themselves largely JavaScript.&lt;/p&gt;

&lt;p&gt;Peter Cooper and I have tried to capture some of this power in the upcoming &lt;a href="http://fluentconf.com/fluent2013?cmp=mp-code-fl13-2ality-promo" rel="nofollow"&gt;Fluent conference&lt;/a&gt;, so that attendees can find their ways to the tools that work for them. &lt;b&gt;Early registration for Fluent ends April 10.&lt;/b&gt; To get a 20% discount, use the registration code “2ALITY”.
&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;Peter and I paused for a moment to talk about what we’re doing and where we see JavaScript and the Web heading.  Though we work together on the conference, our perspectives aren’t quite the same, something I think works out for the better.&lt;/p&gt;

&lt;p&gt;Highlights include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; Different tiers of technology adoption (discussed at the &lt;a href="http://www.youtube.com/watch?v=4JyCJuKb2j8#t=2m41s"&gt;2:41&lt;/a&gt; mark)&lt;/li&gt;
&lt;li&gt; “3-D demos don’t really interest the main market, whereas doing medical visualization, stuff like that, is more mass market” (&lt;a href="http://www.youtube.com/watch?v=4JyCJuKb2j8#t=5m42s"&gt;5:42&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt; “The experimental end with robots … Nodecopter” (&lt;a href="http://www.youtube.com/watch?v=4JyCJuKb2j8#t=9m30s"&gt;9:30&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt; JavaScript crossing over to the server with Node, or a polyglot world? (&lt;a href="http://www.youtube.com/watch?v=4JyCJuKb2j8#t=11m27s"&gt;11:27&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt; Can frameworks or other languages that compile to JavaScript address modularization and code management questions? (&lt;a href="http://www.youtube.com/watch?v=4JyCJuKb2j8#t=14m50s"&gt;14:50&lt;/a&gt;; and more on enterprise development at &lt;a href="http://www.youtube.com/watch?v=4JyCJuKb2j8#t=17m43s"&gt;17:43&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt; Learning from Ruby and Rails’ RJS experience (&lt;a href="http://www.youtube.com/watch?v=4JyCJuKb2j8#t=22m40s"&gt;22:40&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt; Learning JavaScript “to get the job done” (&lt;a href="http://www.youtube.com/watch?v=4JyCJuKb2j8#t=26m8s"&gt;26:08&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You’ll find our full discussion in the following video:&lt;/p&gt;
&lt;iframe width="560" height="315" src="http://www.youtube.com/embed/4JyCJuKb2j8" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;
&lt;hr&gt;
O’Reilly &lt;a href="http://www.2ality.com/p/advertise.html"&gt;sponsors&lt;/a&gt; this week on 2ality.
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/ow-9Gpg9yD8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/7670201567390370726/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=7670201567390370726" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/7670201567390370726?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/7670201567390370726?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/ow-9Gpg9yD8/sponsor-fluent.html" title="[Sponsor] Where are JavaScript and the web going?" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/4JyCJuKb2j8/default.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.2ality.com/2013/04/sponsor-fluent.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QFQHs8eCp7ImA9WhBWFEw.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-2810883957961795984</id><published>2013-04-08T09:41:00.002+02:00</published><updated>2013-04-08T13:08:31.570+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-08T13:08:31.570+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="12quirks" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="jslang" /><title>JavaScript quirk 1: implicit conversion of values</title><content type="html">[This post is part of a &lt;a href="http://www.2ality.com/2013/04/12quirks.html"&gt;series&lt;/a&gt; on JavaScript quirks.]
&lt;p&gt;
JavaScript is very tolerant when it comes to accepting values. For example, everywhere it expects a number, it does not reject values from other types, but tries to convert them:
&lt;pre&gt;
    &amp;gt; '5' - '2'
    3
    &amp;gt; '5' * '2'
    10
&lt;/pre&gt;
Automatic conversion to boolean is rarely problematic and often useful. It is covered here as a preparation for later – we’ll use it to work around quirks. Automatic conversion to string, however, can cause problems.

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h3 class="countheads"&gt;Implicit conversion to boolean: “truthy” and “falsy” values&lt;/h3&gt;

Whenever JavaScript expects a boolean value (e.g. for the condition of an &lt;tt&gt;if&lt;/tt&gt; statement), any value can be used. It will be interpreted as either &lt;tt&gt;true&lt;/tt&gt; or &lt;tt&gt;false&lt;/tt&gt;. The following values are interpreted as &lt;tt&gt;false&lt;/tt&gt;:
&lt;ul&gt;
    &lt;li&gt;&lt;tt&gt;undefined&lt;/tt&gt;, &lt;tt&gt;null&lt;/tt&gt;&lt;/li&gt;
    &lt;li&gt;Boolean: &lt;tt&gt;false&lt;/tt&gt;&lt;/li&gt;
    &lt;li&gt;Number: &lt;tt&gt;-0&lt;/tt&gt;, &lt;tt&gt;+0&lt;/tt&gt;, &lt;tt&gt;NaN&lt;/tt&gt;&lt;/li&gt;
    &lt;li&gt;String: &lt;tt&gt;''&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
All other values are considered &lt;tt&gt;true&lt;/tt&gt;. Values interpreted as &lt;tt&gt;false&lt;/tt&gt; are called &lt;i&gt;falsy&lt;/i&gt;, values interpreted as &lt;tt&gt;true&lt;/tt&gt; are called &lt;i&gt;truthy&lt;/i&gt;. You can use &lt;tt&gt;Boolean&lt;/tt&gt; as a function to test how a value is interpreted. It converts its argument to boolean:
&lt;pre&gt;
    &amp;gt; Boolean(undefined)
    false
    &amp;gt; Boolean(0)
    false
    &amp;gt; Boolean(3)
    true
&lt;/pre&gt;

&lt;h3&gt;Implicit conversion of strings&lt;/h3&gt;

In web development, you often get values as strings that are actually numbers or booleans. For example, when users enter this kind of data in a form. If you forget to explicitly convert these strings then JavaScript will surprise you negatively in two ways: First, there will be no warning. Second, the values will be converted automatically, but wrongly. The plus operator (&lt;tt&gt;+&lt;/tt&gt;), for instance, is problematic, because it concatenates strings as soon as one of its operands is a string. During the following interaction with JavaScript, the assumption is that we are adding 1 to 5. Instead, we are concatenating the strings &lt;tt&gt;'5'&lt;/tt&gt; and &lt;tt&gt;'1'&lt;/tt&gt;.
&lt;pre&gt;
    &amp;gt; var x = '5';  // wrong assumption: x is a number
    &amp;gt; x + 1
    '51'
&lt;/pre&gt;
Furthermore, there are a few falsy values that are truthy if converted to string. Example: &lt;tt&gt;false&lt;/tt&gt;.
&lt;pre&gt;
    &amp;gt; Boolean(false)  // truthy?
    false
    &amp;gt; String(false)
    'false'
    &amp;gt; Boolean('false')  // truthy?
    true
&lt;/pre&gt;
Example: &lt;tt&gt;undefined&lt;/tt&gt;.
&lt;pre&gt;
    &amp;gt; Boolean(undefined)  // truthy?
    false
    &amp;gt; String(undefined)
    'undefined'
    &amp;gt; Boolean('undefined')  // truthy?
    true
&lt;/pre&gt;

&lt;h3&gt;Implicit conversion of objects&lt;/h3&gt;

Objects are only implicitly converted if JavaScript expects a number or a string. In the former case, the conversion takes three steps:
&lt;ol&gt;
    &lt;li&gt;Call &lt;tt&gt;valueOf()&lt;/tt&gt;. If the result is primitive (not an object) then use it and convert it to a number.
    &lt;/li&gt;
    &lt;li&gt;Otherwise, call &lt;tt&gt;toString()&lt;/tt&gt;. If the result is primitive, use it and convert it to a number.
    &lt;/li&gt;
    &lt;li&gt;Otherwise, throw a &lt;tt&gt;TypeError&lt;/tt&gt;.&lt;/li&gt;
&lt;/ol&gt;
Example for step 1:
&lt;pre&gt;
    &amp;gt; 3 * { valueOf: function () { return 5 } }
    15
&lt;/pre&gt;
Example for step 3:
&lt;pre&gt;
    &amp;gt; function returnObject() { return {} }
    &amp;gt; 3 * { valueOf: returnObject, toString: returnObject }
    TypeError: Cannot convert object to primitive value
&lt;/pre&gt;
If JavaScript converts to string, steps 1 and 2 are swapped: &lt;tt&gt;toString()&lt;/tt&gt; is tried first, &lt;tt&gt;valueOf()&lt;/tt&gt; second.

&lt;h3&gt;Best practice: explicit conversion&lt;/h3&gt;

It is best to explicitly convert values to the desired types before using them. A minimal solution is to use the functions &lt;tt&gt;Boolean()&lt;/tt&gt;, &lt;tt&gt;Number()&lt;/tt&gt; and &lt;tt&gt;String()&lt;/tt&gt;:
&lt;pre&gt;
    function handleFormData(formData) {
        var givenName = String(formData.givenName);
        var age = Number(formData.age);
        ...
    }
&lt;/pre&gt;
These functions always return a value (they never throw an exception). However, &lt;tt&gt;Number()&lt;/tt&gt; returns the error value &lt;tt&gt;NaN&lt;/tt&gt; &lt;a class="ptr"&gt;[1]&lt;/a&gt; if it can’t convert a value:
&lt;pre&gt;
    &amp;gt; Number('xyz')
    NaN
    &amp;gt; Number(undefined)
    NaN
    &amp;gt; Number(null)
    0
    &amp;gt; Number(true)
    1
&lt;/pre&gt;
A more elaborate solution would be to first check whether the value you are converting has the correct format (e.g. someone shouldn’t enter &lt;tt&gt;'xyz'&lt;/tt&gt; as their age) and to take appropriate measures if it doesn’t.

&lt;h3&gt;Reference&lt;/h3&gt;

&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2012/02/nan-infinity.html"&gt;NaN and Infinity in JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/gacP9AB3jlA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/2810883957961795984/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=2810883957961795984" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/2810883957961795984?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/2810883957961795984?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/gacP9AB3jlA/quirk-implicit-conversion.html" title="JavaScript quirk 1: implicit conversion of values" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>8</thr:total><feedburner:origLink>http://www.2ality.com/2013/04/quirk-implicit-conversion.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEADR3gzeSp7ImA9WhBaE00.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-8775442752043147224</id><published>2013-04-08T08:42:00.003+02:00</published><updated>2013-05-23T11:52:56.681+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-23T11:52:56.681+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="12quirks" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="jslang" /><title>12 JavaScript quirks</title><content type="html">A core of JavaScript (the so-called “good parts”) is elegant, but that core is often obscured by quirks. This introduction is the first of a series of blog posts that looks at twelve common quirks and how to best deal with them:
&lt;a name='more'&gt;&lt;/a&gt;
&lt;ol&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/04/quirk-implicit-conversion.html"&gt;Implicit conversion of values&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/04/quirk-undefined.html"&gt;Two “non-values” – &lt;tt&gt;undefined&lt;/tt&gt; and &lt;tt&gt;null&lt;/tt&gt;&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/04/quirk-equality.html"&gt;Normal equality (&lt;tt&gt;==&lt;/tt&gt;)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/04/quirk-automatic-globals.html"&gt;Unknown variable names create global variables&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/05/quirk-parameters.html"&gt;Parameter handling&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/05/quirk-variable-scope.html"&gt;The scope of variables&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/05/quirk-closures.html"&gt;Inadvertent sharing of variables via closures&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;Array-like objects&lt;/li&gt;
    &lt;li&gt;Subtyping constructors&lt;/li&gt;
    &lt;li&gt;Reading and writing of properties&lt;/li&gt;
    &lt;li&gt;&lt;tt&gt;this&lt;/tt&gt; in real functions&lt;/li&gt;
    &lt;li&gt;The for-in loop&lt;/li&gt;
&lt;/ol&gt;
A concluding post will cover ECMAScript 6 &lt;a class="ptr"&gt;[1]&lt;/a&gt;, which will eliminate most of the above quirks.
&lt;p&gt;
The series will provide a good overview of JavaScript. It is a translation of a &lt;a href="http://www.2ality.com/2013/01/fallgruben.html"&gt;previous blog post&lt;/a&gt; in German.
ECMAScript 5 will be used and a basic knowledge of JavaScript is required, but much will be explained. I will post one quirk per week.
&lt;p&gt;
&lt;b&gt;Reference:&lt;/b&gt;
&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2011/06/ecmascript.html"&gt;ECMAScript: ES.next versus ES 6 versus ES Harmony&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/CrXP-YBBOQo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/8775442752043147224/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=8775442752043147224" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/8775442752043147224?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/8775442752043147224?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/CrXP-YBBOQo/12quirks.html" title="12 JavaScript quirks" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>10</thr:total><feedburner:origLink>http://www.2ality.com/2013/04/12quirks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkEGQXs8eSp7ImA9WhBWEUg.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-6909810925115687673</id><published>2013-04-05T11:28:00.000+02:00</published><updated>2013-04-05T11:37:00.571+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-05T11:37:00.571+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="webkit" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="blink" /><category scheme="http://www.blogger.com/atom/ns#" term="chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><category scheme="http://www.blogger.com/atom/ns#" term="webdev" /><category scheme="http://www.blogger.com/atom/ns#" term="browser" /><title>Google’s Blink: a few interesting facts</title><content type="html">With &lt;a href="http://www.chromium.org/blink"&gt;Blink&lt;/a&gt;, Google has created a permanent fork of the WebKit HTML engine. This blog post mentions a few interesting facts that provide context for that decision.

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h3 class="countheads"&gt;How much did each company contribute to WebKit?&lt;/h3&gt;

There are several interesting diagrams and numbers in the article “&lt;a href="http://blog.bitergia.com/2013/03/01/reviewers-and-companies-in-webkit-project/"&gt;Reviewers and companies in the WebKit project&lt;/a&gt;” (by Daniel Izquierdo Cortázar for Bitergia).
It’s remarkable how much Google has recently contributed to WebKit. Obviously, not all contributions are created equal: some benefit everyone, others only the contributor. We don’t know what the ratio between the two kinds is for Apple, Google, etc.

&lt;h3&gt;Why didn’t WebKit2 adopt Chrome’s multiprocess architecture?&lt;/h3&gt;

Here is an Apple employee’s &lt;a href="https://news.ycombinator.com/item?id=5490242"&gt;explanation&lt;/a&gt; of why WebKit2 has a multiprocess architecture that is different from Chrome’s:
&lt;blockquote&gt;
    Before we wrote a single line of what would become WebKit2 we directly asked Google folks if they would be willing to contribute their multiprocess support back to WebKit, so that we could build on it. They said no.
&lt;/blockquote&gt;
The link also contains answers from Googlers to that assertion.

&lt;h3&gt;How will WebKit change without Chrome support?&lt;/h3&gt;

It will become &lt;a href="https://lists.webkit.org/pipermail/webkit-dev/2013-April/024388.html"&gt;simpler&lt;/a&gt;. For example, quite a few conditional code sections can be removed, especially those for supporting two JavaScript engines (JSC = JavaScriptCore and V8):
&lt;pre&gt;
    #if USE(V8)
    #if !USE(JSC)
    #if PLATFORM(CHROMIUM)
    #if USE(GOOGLEURL)
&lt;/pre&gt;
GOOGLEURL is URL-handling code where Google uses its own library, Google-URL. It’s interesting that the split has existed &lt;a href="https://lists.webkit.org/pipermail/webkit-dev/2008-October/005200.html"&gt;since 2008&lt;/a&gt;.

&lt;h3&gt;Conclusion&lt;/h3&gt;

It’s impossible to know Google’s exact motivations behind the fork (freedom to do their own thing, not wanting to help Apple, etc.). There probably was no single dominant motivation. The future will be interesting:
How hard will Google push its own technologies Native Client and Dart? How will this affect the rest of Blink? How much will Google collaborate with other companies? It looks like they will continue their current strategy of hedging their bets. A good example is a recently filed &lt;a href="https://code.google.com/p/v8/issues/detail?id=2599"&gt;issue&lt;/a&gt; for adding asm.js &lt;a class="ptr"&gt;[1]&lt;/a&gt; support to V8. asm.js can be seen as a competitor to Native Client.
&lt;p&gt;
All things considered, forking WebKit seems the best solution for everyone involved, as far as the browser implementation side is concerned. Web developers will have to wait and see, but there are &lt;i&gt;already&lt;/i&gt; many subtle differences between the variants of WebKit.

&lt;h3&gt;Reference&lt;/h3&gt;

&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/02/asm-js.html"&gt;asm.js: closing the gap between JavaScript and native&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/VSF8pB5ktSI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/6909810925115687673/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=6909810925115687673" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/6909810925115687673?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/6909810925115687673?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/VSF8pB5ktSI/blink.html" title="Google’s Blink: a few interesting facts" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.2ality.com/2013/04/blink.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEDRX8yfCp7ImA9WhBWEEU.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-48043076146368123</id><published>2013-04-04T07:58:00.002+02:00</published><updated>2013-04-04T16:44:34.194+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-04T16:44:34.194+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="jslang" /><title>Enforcing toString()</title><content type="html">JavaScript usually automatically converts values to the type that a method or operator needs, which can lead to a variety of bugs. As a counter-measure, Brian McKenna (&lt;a href="https://twitter.com/puffnfresh"&gt;@puffnfresh&lt;/a&gt;) &lt;a href="https://twitter.com/puffnfresh/status/316630924198572032"&gt;suggests&lt;/a&gt; using the following code for your tests:
&lt;pre&gt;
    Object.prototype.valueOf = function () {
        throw new Error('Use an explicit toString');
    };
&lt;/pre&gt;
&lt;a name='more'&gt;&lt;/a&gt;
What is the effect of this code? You now can’t use the plus operator to convert an object to string, any more:
&lt;pre&gt;
    &amp;gt; var obj = {};

    &amp;gt; 'Hello '+obj
    Error: Use an explicit toString

    &amp;gt; String(obj)
    '[object Object]'
    &amp;gt; obj.toString()
    '[object Object]'

    &amp;gt; 'Hello '+String(obj)
    'Hello [object Object]'
&lt;/pre&gt;
How does this work?
To convert an object to a specific primitive type T, it is first converted to any primitive value which is then converted to T. The former conversion happens in two steps &lt;a class="ptr"&gt;[1]&lt;/a&gt;:
&lt;ul&gt;
    &lt;li&gt;Call method &lt;tt&gt;valueOf()&lt;/tt&gt;. If it returns a primitive, we are done.
    &lt;/li&gt;
    &lt;li&gt;Otherwise, call method &lt;tt&gt;toString()&lt;/tt&gt;. If it returns a primitive, we are done.
    &lt;/li&gt;
    &lt;li&gt;Otherwise, throw an error.&lt;/li&gt;
&lt;/ul&gt;
The above order of first invoking &lt;tt&gt;valueOf()&lt;/tt&gt; and then &lt;tt&gt;toString()&lt;/tt&gt; is chosen if the final conversion is to a number. If the final conversion is to string then &lt;tt&gt;toString()&lt;/tt&gt; is invoked first. The plus operator converts to either number or string, but it produces a first primitive via the “number” algorithm &lt;a class="ptr"&gt;[2]&lt;/a&gt;.
&lt;p&gt;
Without the code snippet at the beginning of this post, &lt;tt&gt;Object.prototype.valueOf()&lt;/tt&gt; returns &lt;tt&gt;this&lt;/tt&gt; (an object) and is inherited by all objects that don’t override this method:
&lt;pre&gt;
    &amp;gt; var obj = {};
    &amp;gt; obj.valueOf() === obj
    true
&lt;/pre&gt;
The plus operator therefore eventually calls &lt;tt&gt;toString()&lt;/tt&gt;. The code snippet prevents that and throws an error before the operator can get to that method.
Note that the error message is not always completely correct:
&lt;pre&gt;
    &amp;gt; Number(obj)
    Error: Use an explicit toString
&lt;/pre&gt;
But this trick can still be useful. If an object really wants to be converted to a number then it will bring its own &lt;tt&gt;valueOf()&lt;/tt&gt;, anyway.

&lt;h3&gt;References&lt;/h3&gt;

&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2012/11/coercing-objects.html"&gt;Coercing objects to primitives&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2012/01/object-plus-object.html"&gt;What is {} + {} in JavaScript?&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/TTTHJMHx6ug" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/48043076146368123/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=48043076146368123" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/48043076146368123?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/48043076146368123?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/TTTHJMHx6ug/enforcing-tostring.html" title="Enforcing toString()" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.2ality.com/2013/04/enforcing-tostring.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cDR384fSp7ImA9WhBXGE4.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-2716260732871902853</id><published>2013-04-01T18:50:00.003+02:00</published><updated>2013-04-01T18:51:16.135+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-01T18:51:16.135+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="esnext" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="nodejs" /><title>ECMAScript Harmony features in Node.js</title><content type="html">Quick tip (via &lt;a href="https://twitter.com/David_Klassen/"&gt;David Klassen&lt;/a&gt;): The following shell command lists all (highly experimental!) ECMAScript Harmony &lt;a class="ptr"&gt;[1]&lt;/a&gt; features that can be switched on in Node.js.
&lt;pre&gt;
    node --v8-options | grep harmony
&lt;/pre&gt;
&lt;a name='more'&gt;&lt;/a&gt;
For example, Node.js 0.10.2 supports:
&lt;p&gt;
&lt;table class="framed"&gt;
 &lt;tr&gt;&lt;td&gt;&lt;tt&gt;--harmony_typeof&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;enable harmony semantics for &lt;tt&gt;typeof&lt;/tt&gt;&lt;/td&gt;&lt;/tr&gt;

 &lt;tr&gt;&lt;td&gt;&lt;tt&gt;--harmony_scoping&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;enable harmony block scoping&lt;/td&gt;&lt;/tr&gt;

 &lt;tr&gt;&lt;td&gt;&lt;tt&gt;--harmony_modules&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;enable harmony modules (implies block scoping)&lt;/td&gt;&lt;/tr&gt;
 &lt;tr&gt;&lt;td&gt;&lt;tt&gt;--harmony_proxies&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;enable harmony proxies&lt;/td&gt;&lt;/tr&gt;
 &lt;tr&gt;&lt;td&gt;&lt;tt&gt;--harmony_collections&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;enable harmony collections (sets, maps, and weak maps)&lt;/td&gt;&lt;/tr&gt;
 &lt;tr&gt;&lt;td&gt;&lt;tt&gt;--harmony&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;enable all harmony features (except &lt;tt&gt;typeof&lt;/tt&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;
Note: “harmony semantics for &lt;tt&gt;typeof&lt;/tt&gt;” is something that (unfortunately) had to be rejected for Harmony. It would have consisted of &lt;tt&gt;typeof null&lt;/tt&gt; returning &lt;tt&gt;'null'&lt;/tt&gt;, but that change would break too much existing code.
&lt;p&gt;
&lt;b&gt;Reference:&lt;/b&gt;
&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2011/06/ecmascript.html"&gt;ECMAScript: ES.next versus ES 6 versus ES Harmony&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/xq0kVFJQKaA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/2716260732871902853/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=2716260732871902853" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/2716260732871902853?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/2716260732871902853?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/xq0kVFJQKaA/nodejs-harmony.html" title="ECMAScript Harmony features in Node.js" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.2ality.com/2013/04/nodejs-harmony.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04BSXs7eip7ImA9WhBXFEk.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-1167680775815744729</id><published>2013-03-28T06:51:00.001+01:00</published><updated>2013-03-28T06:52:38.502+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-28T06:52:38.502+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="jslang" /><category scheme="http://www.blogger.com/atom/ns#" term="jshistory" /><title>Ecma wasn’t always Ecma</title><content type="html">Most people know that ECMAScript is the language standard behind JavaScript &lt;a class="ptr"&gt;[1]&lt;/a&gt;. Fewer people know that its name comes from &lt;a href="http://en.wikipedia.org/wiki/Ecma_International"&gt;Ecma International&lt;/a&gt;, the organization managing this standard. Interestingly, that organization started as “European Computer Manufacturers Association (ECMA)”, but renamed itself to “Ecma International” in 1994. That was done to reflect its increasingly international focus. Ecma is now not considered an acronym, any more. Ecma International is located in Geneva. In contrast, TC39 &lt;a class="ptr"&gt;[1]&lt;/a&gt;, the Ecma-hosted committee evolving ECMAScript, is rather USA-centric (true to where JavaScript was created and who created it) and usually meets somewhere in California.

&lt;a name='more'&gt;&lt;/a&gt;
&lt;p&gt;
This little bit of history also explains why it’s spelled ECMAScript and not EcmaScript: That’s a remnant from when Ecma was still ECMA.
&lt;p&gt;
&lt;b&gt;Reference:&lt;/b&gt;
&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2011/06/ecmascript.html"&gt;ECMAScript: ES.next versus ES 6 versus ES Harmony&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/LEfLBjImgpI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/1167680775815744729/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=1167680775815744729" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/1167680775815744729?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/1167680775815744729?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/LEfLBjImgpI/ecma.html" title="Ecma wasn’t always Ecma" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.2ality.com/2013/03/ecma.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0MDR3c9eSp7ImA9WhBXEUU.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-5376871057303589617</id><published>2013-03-24T19:27:00.000+01:00</published><updated>2013-03-25T04:17:56.961+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-25T04:17:56.961+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><category scheme="http://www.blogger.com/atom/ns#" term="jsfuture" /><title>Parallel JS (River Trail): soon in Firefox</title><content type="html">Parallel JS will soon be included in Firefox Nightly builds. This project was initially called River Trail &lt;a class="ptr"&gt;[1]&lt;/a&gt;. It automatically parallelizes code that uses the &lt;tt&gt;ParallelArray&lt;/tt&gt; type and its array-like methods (&lt;tt&gt;map()&lt;/tt&gt; etc.). [Source of this post: “&lt;a href="http://smallcultfollowing.com/babysteps/blog/2013/03/20/parallel-js-lands/"&gt;Parallel JS lands&lt;/a&gt;” by Nicholas D. Matsakis.]
&lt;a name='more'&gt;&lt;/a&gt;
&lt;p&gt;
Time table:
&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;Now:&lt;/b&gt; Only a limited subset of JavaScript is supported and you don’t get good feedback as to whether your code could be parallelized and if not, why not.
    &lt;/li&gt;
    &lt;li&gt;&lt;b&gt;Medium term:&lt;/b&gt; All &lt;i&gt;pure functions&lt;/i&gt; (that don’t mutate shared state, only data that they create and store in local variables) will be parallelizable; better diagnostics when parallelization is not possible.
    &lt;/li&gt;
    &lt;li&gt;&lt;b&gt;Long term:&lt;/b&gt; Make parallelization as wide-spread in JavaScript as possible and evolve the API. One &lt;a href="http://smallcultfollowing.com/babysteps/blog/2013/02/26/splitting-the-pjs-api/"&gt;possible improvement&lt;/a&gt; is to bring parallelization to normal arrays. Currently, &lt;tt&gt;ParallelArray&lt;/tt&gt; pulls double duty, it is both a lightweight array that can be manipulated in parallel and a capable multi-dimensional matrix. Matsakis proposes adding parallelizing methods to arrays (e.g. &lt;tt&gt;unorderedMap()&lt;/tt&gt;), so that &lt;tt&gt;ParallelArray&lt;/tt&gt; can focus on the latter duty.
    &lt;/li&gt;
&lt;/ul&gt;
Related blog post, with more information on Parallel JS:
&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2012/10/river-trail-firefox.html"&gt;JavaScript: parallel programming via River Trail coming to Firefox&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/GEBWq5gGobs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/5376871057303589617/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=5376871057303589617" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/5376871057303589617?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/5376871057303589617?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/GEBWq5gGobs/parallel-js.html" title="Parallel JS (River Trail): soon in Firefox" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.2ality.com/2013/03/parallel-js.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQASXgyeyp7ImA9WhBQGE8.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-606325738593754254</id><published>2013-03-21T02:12:00.003+01:00</published><updated>2013-03-21T02:12:28.693+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-21T02:12:28.693+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="esnext" /><category scheme="http://www.blogger.com/atom/ns#" term="tc39" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><title>ECMAScript 6: TC39’s January 2013 meeting</title><content type="html">TC39 &lt;a class="ptr"&gt;[1]&lt;/a&gt; is the committe that currently plans ECMAScript 6 (code-named ECMAScript.next), the next version of the JavaScript language standard. January 29–31, they had another meeting. Thanks to Rick Waldron’s &lt;a href="https://github.com/rwldrn/tc39-notes/tree/master/es6/2013-01"&gt;notes&lt;/a&gt;, we can read up on what has been decided. This blog post describes the highlights. Previous &lt;a href="http://www.2ality.com/search/label/tc39"&gt;blog posts&lt;/a&gt; summarized prior meetings.
&lt;p&gt;
(Note: a blog post on the &lt;a href="https://github.com/rwldrn/tc39-notes/tree/master/es6/2013-03"&gt;March TC39 meeting&lt;/a&gt; will be posted at some time in the future.)

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h3 class="countheads"&gt;January 29&lt;/h3&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;b&gt;&lt;tt&gt;Object.is()&lt;/tt&gt;:&lt;/b&gt; strict equality (&lt;tt&gt;===&lt;/tt&gt;) is safer than sloppy equality (&lt;tt&gt;==&lt;/tt&gt;). But it still has the quirk of &lt;tt&gt;NaN&lt;/tt&gt; not being equal to itself &lt;a class="ptr"&gt;[2]&lt;/a&gt;. The original plan for ECMAScript 6 was to introduce an &lt;tt&gt;is&lt;/tt&gt; operator that fixes this quirk, but those plans have been abandoned. Instead, you can use &lt;tt&gt;Object.is(op1, op2)&lt;/tt&gt; if you need “stricter” equality &lt;a class="ptr"&gt;[2]&lt;/a&gt;. &lt;tt&gt;Object.is()&lt;/tt&gt; also distinguishes positive and negative zero &lt;a class="ptr"&gt;[3]&lt;/a&gt; (which isn’t always desirable).
    &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.ecma-international.org/ecma-402/1.0/"&gt;&lt;b&gt;ECMAScript Internationalization API (ECMA-402):&lt;/b&gt;&lt;/a&gt; Chrome 24 shipped with an (unprefixed) implementation of the first edition of ECMA-402. Thanks to the API, the methods &lt;tt&gt;String.prototype.localeCompare&lt;/tt&gt;, &lt;tt&gt;{Date,Number}.prototype.toLocaleString&lt;/tt&gt; get meaningful implementations (until now, they didn’t do anything locale-specific on most JavaScript engines). Work to specify the second edition of ECMA-402 continues.
    &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;January 30&lt;/h3&gt;

&lt;h4&gt;Static methods&lt;/h4&gt;

ECMAScript 6 will allow one to define &lt;a href="http://wiki.ecmascript.org/doku.php?id=strawman:class_method_syntax"&gt;static methods&lt;/a&gt; (constructor methods) in classes. For example:
&lt;pre&gt;
    class Point {
        constructor(x, y) {
            this.x = x;
            this.y = y;
        }
        static zero() {
            return new Point(0, 0);
        }
    }
&lt;/pre&gt;
        This is the same as:
&lt;pre&gt;
    class Point {
        constructor(x, y) {
            this.x = x;
            this.y = y;
        }
    }
    Object.mixin(Point, {
        zero() {
            return new Point(0, 0);
        }
    });
&lt;/pre&gt;

&lt;h4&gt;An &lt;tt&gt;Array.prototype.map()&lt;/tt&gt; that doesn’t return an array&lt;/h4&gt;

Arrays have several methods that create a new array based on the current one. For example, &lt;tt&gt;concat&lt;/tt&gt; and &lt;tt&gt;filter&lt;/tt&gt;. If those methods are invoked on a subtype of &lt;tt&gt;Array&lt;/tt&gt;, it is obvious what type the result should have: the same type as &lt;tt&gt;this&lt;/tt&gt;. For &lt;tt&gt;map&lt;/tt&gt;, things are more complicated: that method is translating from one kind of value to another one and you sometimes might want to change the collection that the result is in, too. Hence, subtypes of &lt;tt&gt;Array&lt;/tt&gt; will inherit the following method (Array-like types might get it, too):
&lt;pre&gt;
    Array.from(iterable, mapFunction?, thisValue?)
&lt;/pre&gt;
Compared to a previous version &lt;a class="ptr"&gt;[4]&lt;/a&gt;, the second and third parameter are new.
The receiver (&lt;tt&gt;this&lt;/tt&gt;) of &lt;tt&gt;from()&lt;/tt&gt; determines which subtype of &lt;tt&gt;Array&lt;/tt&gt; the result will be stored in. Example from the Waldron’s notes:
&lt;pre&gt;
    // Turn an array of nodeNames into NodeList of nodes
    NodeList.from( ["div"], node =&gt; document.createElement(node) );
&lt;/pre&gt;


&lt;h4&gt;Destructuring is refutable by default&lt;/h4&gt;

Destructuring is used when a value is ready to be stored somewhere: it allows you to extract data from that value via patterns on the receiving end (left-hand side of an assignment, parameter definitions, etc.).
Refutable matching means that the extraction can fail and throw an exception. It has been decided that refutability should be the default for destructuring in ECMAScript 6 (“fail-fast” operation). That is, destructuring only succeeds if the value to be stored completely matches the pattern:
&lt;pre&gt;
    { first: f, last: l } = { first: 'Jane', last: 'Doe' };  // succeeds
    { first: f, last: l } = { first: 'Jane' };  // fails
&lt;/pre&gt;
You can, however introduce irrefutability by suffixing parts of the pattern with a question mark (rule of thumb: the question mark follows pattern parts, not variables):
&lt;pre&gt;
    { first: f, last?: l } = { first: 'Jane' };  // succeeds
    console.log(l);  // undefined
&lt;/pre&gt;
Another possibility is to give a left-hand-side variable a default value:
&lt;pre&gt;
    { first: f, last: l = 'Unknown' } = { first: 'Jane' };  // succeeds
    console.log(l);  // Unknown
&lt;/pre&gt;
A default value is triggered if the part of the pattern is missing or if its value is &lt;tt&gt;undefined&lt;/tt&gt;:
&lt;pre&gt;
    let { a: x = 1 } = { a: undefined }
    console.log(x);  // 1
&lt;/pre&gt;
You can also make all of a pattern irrefutable:
&lt;pre&gt;
    let { foo: f }? = options;  // always succeeds
&lt;/pre&gt;
&lt;tt&gt;f&lt;/tt&gt; becomes &lt;tt&gt;undefined&lt;/tt&gt; if &lt;tt&gt;options&lt;/tt&gt; is &lt;tt&gt;undefined&lt;/tt&gt; or &lt;tt&gt;null&lt;/tt&gt; or does not have a property &lt;tt&gt;foo&lt;/tt&gt;. This example shows that irrefutability is “deep”: if you mark a part as irrefutable, the parts inside of it become irrefutable, too. A &lt;a href="http://wiki.ecmascript.org/doku.php?id=harmony:refutable_matching"&gt;proposal&lt;/a&gt; on the ECMAScript wiki has details on refutable matching, but uses a slightly different syntax (prefix question marks).

&lt;h4&gt;Property &lt;tt&gt;name&lt;/tt&gt; of functions&lt;/h4&gt;

ECMAScript 6 will standardize the &lt;a href="http://wiki.ecmascript.org/doku.php?id=strawman:name_property_of_functions"&gt;property &lt;tt&gt;name&lt;/tt&gt;&lt;/a&gt; of functions.
Its main use is debugging: you get a name if you log a function and debuggers can use the name, too. ECMAScript 6 will try to fill in the name as best it can: In addition to the obvious cases (function declaration, named function expression, method definition), a function will also get a name if it is the initial value of a variable declaration (&lt;tt&gt;var&lt;/tt&gt;, &lt;tt&gt;let&lt;/tt&gt;, &lt;tt&gt;const&lt;/tt&gt;) or a property value inside an object literal.

&lt;h4&gt;TypedArray becomes part of ECMAScript&lt;/h4&gt;

TypedArray is a JavaScript type that was created for WebGL to handle binary data. TC39 will move this standard into ECMAScript 6. In the process, it can become a more organic part of the language (e.g. become more similar to arrays).

&lt;h3&gt;January 31&lt;/h3&gt;

&lt;b&gt;Modules&lt;/b&gt; are still work in progress. The following subsections describe other decisions.

&lt;h4&gt;Refining the semantics of classes&lt;/h4&gt;

Classes can’t extend non-constructors. If you write a class:
&lt;pre&gt;
    class Foo extends &lt;i&gt;X&lt;/i&gt; { ... }
&lt;/pre&gt;
        Then &lt;tt&gt;X&lt;/tt&gt; must be a constructor (&lt;tt&gt;X&lt;/tt&gt; will become &lt;tt&gt;Foo&lt;/tt&gt;’s prototype and &lt;tt&gt;X.prototype&lt;/tt&gt; will become &lt;tt&gt;Foo.prototype&lt;/tt&gt;’s prototype). You can, however extend &lt;tt&gt;null&lt;/tt&gt;:
&lt;pre&gt;
    class Bar extends null { ... }
&lt;/pre&gt;
        Roughly, this is syntactic sugar for:
&lt;pre&gt;
    function Bar() { ... }
    Bar.prototype = Object.create(null);
    ...
&lt;/pre&gt;

&lt;h4&gt;Map/Set comparator&lt;/h4&gt;

You will be able to configure how these ECMAScript 6 data structures compare keys or values in order to implement the operations &lt;tt&gt;get&lt;/tt&gt;, &lt;tt&gt;set&lt;/tt&gt;, &lt;tt&gt;has&lt;/tt&gt;, &lt;tt&gt;delete&lt;/tt&gt;. The new signatures are (the second parameter is new):
&lt;pre&gt;
    new Map(iterator = undefined, comparator = undefined)
    new Set(iterator = undefined, comparator = undefined)
&lt;/pre&gt;
If you don’t specify a comparator, a “default comparator” is used that works like &lt;tt&gt;===&lt;/tt&gt; &lt;a class="ptr"&gt;[6]&lt;/a&gt;, but considers &lt;tt&gt;NaN&lt;/tt&gt; to be equal to itself. Otherwise you wouldn’t be able do anything with &lt;tt&gt;NaN&lt;/tt&gt;, apart from adding it to a collection. Alternatively, you can also specify the comparator to be &lt;tt&gt;'is'&lt;/tt&gt;, which means that &lt;tt&gt;Object.is()&lt;/tt&gt; will be used &lt;a class="ptr"&gt;[2]&lt;/a&gt;. That function works like the default comparator, but distinguishes &lt;tt&gt;+0&lt;/tt&gt; and &lt;tt&gt;-0&lt;/tt&gt; &lt;a class="ptr"&gt;[3]&lt;/a&gt;.

&lt;h4&gt;Simplified syntax for array comprehensions and generator comprehensions&lt;/h4&gt;

Previously, array comprehensions &lt;a class="ptr"&gt;[7]&lt;/a&gt; looked like this:
&lt;pre&gt;
    let arr = [x for x of itr if x &amp;gt; 0];
&lt;/pre&gt;
        This has been changed to:
&lt;pre&gt;
    let arr = [for (x of itr) if (x &amp;gt; 0) x];
&lt;/pre&gt;
Now the element expression comes last, which is more similar to the structure of an implementation that uses loops. The expression is preceded by zero or more comprehension clauses. Those clauses now have parenthesized syntax. There previously was a &lt;tt&gt;let&lt;/tt&gt; clause, which may or may not be added after ECMAScript 6. Arguably, &lt;tt&gt;let&lt;/tt&gt; would make comprehensions more complex, while their main appeal is simplicity. Details of the new syntax are described in a &lt;a href="https://gist.github.com/dherman/b250d1fad15dbb5f77a5"&gt;gist&lt;/a&gt; by David Herman.

&lt;h3&gt;References&lt;/h3&gt;

&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2011/06/ecmascript.html"&gt;ECMAScript: ES.next versus ES 6 versus ES Harmony&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2012/03/stricter-equality.html"&gt;Stricter equality in JavaScript&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2012/03/signedzero.html"&gt;JavaScript’s two zeros&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2011/07/array-from.html"&gt;ECMAScript.next: Array.from() and Array.of()&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/02/foreach-es6.html"&gt;ECMAScript 6’s parameter destructuring and forEach()&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2011/06/javascript-equality.html"&gt;Equality in JavaScript: === versus ==&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/01/comprehensions.html"&gt;ECMAScript.next: array comprehensions and generator comprehensions&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/hfcdODO9IAY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/606325738593754254/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=606325738593754254" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/606325738593754254?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/606325738593754254?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/hfcdODO9IAY/tc39-january.html" title="ECMAScript 6: TC39’s January 2013 meeting" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.2ality.com/2013/03/tc39-january.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkYHRXo5eip7ImA9WhBQFk4.&quot;"><id>tag:blogger.com,1999:blog-8100407163665430627.post-5859166833396397490</id><published>2013-03-18T16:40:00.000+01:00</published><updated>2013-03-18T20:15:34.422+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-18T20:15:34.422+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="esnext" /><category scheme="http://www.blogger.com/atom/ns#" term="dev" /><title>Subclassing builtins in ECMAScript 6</title><content type="html">In JavaScript, it is difficult to create sub-constructors of built-in constructors such as &lt;tt&gt;Array&lt;/tt&gt;. This blog post explains the problem and possible solutions – including one that will probably be chosen by ECMAScript 6. The post is based on Allen Wirfs-Brock’s &lt;a href="http://wiki.ecmascript.org/lib/exe/fetch.php?id=meetings%3Ameeting_jan_29_2013&amp;amp;cache=cache&amp;amp;media=meetings:subclassing_builtins.pdf"&gt;slides&lt;/a&gt; from a presentation he held on January 29, during a TC39 meeting.

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h3 class="countheads"&gt;The problem&lt;/h3&gt;

Creating sub-constructors of built-in constructors is difficult to impossible. The normal pattern for subtyping in JavaScript is (ignoring the property &lt;tt&gt;constructor&lt;/tt&gt; &lt;a class="ptr"&gt;[1]&lt;/a&gt;):
&lt;pre&gt;
    function SuperConstr(arg1) {
        ...
    }
    function SubConstr(arg1, arg2) {
        SuperConstr.call(this, arg1);
    }
    SubConstr.prototype = Object.create(SuperConstr.prototype);    
&lt;/pre&gt;

If you want to use this pattern with built-in constructors, you are facing problems. The following example demonstrates those problems for &lt;tt&gt;Array&lt;/tt&gt;; they are similar for other builtins.

&lt;h4&gt;Trying to subtype Array&lt;/h4&gt;

Take, for example, the following code, where we try to subtype &lt;tt&gt;Array&lt;/tt&gt;.

&lt;pre&gt;
    function MyArray(len) {
        Array.call(this, len);
    }
    MyArray.prototype = Object.create(Array.prototype);    
&lt;/pre&gt;

This doesn’t work:
&lt;pre&gt;
    &amp;gt; var a = new MyArray();
    &amp;gt; a[2] = 'abc';
    &amp;gt; a.length
    0
&lt;/pre&gt;
Compare: a normal array.
&lt;pre&gt;
    &amp;gt; var b = [];
    &amp;gt; b[2] = 'abc';
    &amp;gt; b.length
    3
&lt;/pre&gt;

If you invoke a constructor &lt;tt&gt;C&lt;/tt&gt; via &lt;tt&gt;new C(arg1, arg2, ...)&lt;/tt&gt;, two steps happen (in the internal &lt;a href="http://ecma-international.org/ecma-262/5.1/#sec-13.2.2"&gt;[[Construct]] method&lt;/a&gt; that every function has):
&lt;ol&gt;
    &lt;li&gt;Allocation: create an instance &lt;tt&gt;inst&lt;/tt&gt;, an object whose prototype is &lt;tt&gt;C.prototype&lt;/tt&gt; (if that value is not an object, use &lt;tt&gt;Object.prototype&lt;/tt&gt;).
    &lt;/li&gt;
    &lt;li&gt;Initialization: Initialize &lt;tt&gt;inst&lt;/tt&gt; via &lt;tt&gt;C.call(inst, arg1, arg2, ...)&lt;/tt&gt;. If the result of that call is an object, return it. Otherwise, return &lt;tt&gt;inst&lt;/tt&gt;.
    &lt;/li&gt;
&lt;/ol&gt;
There are obstacles to both steps when you try to subtype &lt;tt&gt;Array&lt;/tt&gt;.

&lt;h4&gt;Allocation obstacle: MyArray allocates the wrong kind of object&lt;/h4&gt;

Array instances are special – the ECMAScript 6 specification calls them &lt;i&gt;exotic&lt;/i&gt;. Their handling of the property &lt;tt&gt;length&lt;/tt&gt; can’t be replicated via normal JavaScript. If you invoke the constructor &lt;tt&gt;MyArray&lt;/tt&gt; then an instance of &lt;tt&gt;MyArray&lt;/tt&gt; is created, not an exotic object.

&lt;h4&gt;Initialization obstacle: MyArray can’t use Array for initialization&lt;/h4&gt;

It is impossible to hand an existing object to &lt;tt&gt;Array&lt;/tt&gt; via &lt;tt&gt;this&lt;/tt&gt; – it completely ignores its &lt;tt&gt;this&lt;/tt&gt; and always creates a new instance.

&lt;pre&gt;
    &amp;gt; var a = [];
    &amp;gt; var b = Array.call(a, 3);
    &amp;gt; a === b   // b is a new object
    false
    &amp;gt; b.length
    3
    &amp;gt; a.length   // a is unchanged
    0
&lt;/pre&gt;

Thus, the &lt;tt&gt;Array.call(...)&lt;/tt&gt; in the first line of &lt;tt&gt;MyArray&lt;/tt&gt; does not work.

&lt;h3&gt;Solutions&lt;/h3&gt;

&lt;h4&gt;Solution: __proto__&lt;/h4&gt;

On JavaScript engines that support &lt;tt&gt;__proto__&lt;/tt&gt; &lt;a class="ptr"&gt;[2]&lt;/a&gt;, you can do the following:

&lt;pre&gt;
    function MyArray(len) {
        var inst = new Array(len);
        inst.__proto__ = MyArray.prototype;
        return inst;
    }
    MyArray.prototype = Object.create(Array.prototype);    
&lt;/pre&gt;

Apart from changing the prototype of an existing object being a relatively costly operation, the biggest disadvantage of this solution is that you can’t subtype &lt;tt&gt;MyArray&lt;/tt&gt; in a normal manner, either.
&lt;p&gt;
This is the only solution that works in current browsers (that support &lt;tt&gt;__proto__&lt;/tt&gt;).

&lt;h4&gt;Non-solution: constructors make objects exotic&lt;/h4&gt;

One could change the &lt;tt&gt;Array&lt;/tt&gt; constructor so that it makes objects that are passed to it exotic. But then one faces difficulties: Some exotic objects have a special structure that you can’t add to an object after the fact. And it would allow one to add several exotic features to the same object (e.g. by first calling &lt;tt&gt;Array&lt;/tt&gt; and then &lt;tt&gt;Date&lt;/tt&gt;), which could lead to conflicts and other problems.

&lt;h4&gt;ECMAScript 6 solution: decouple allocation and initialization&lt;/h4&gt;

Specification-wise, the &lt;tt&gt;new&lt;/tt&gt; operator invokes the internal &lt;tt&gt;[[Construct]]&lt;/tt&gt; method, which roughly looks like this:
&lt;pre&gt;
    Function.prototype.[[Construct]] = function (...args) {
        let Constr = this;

        // Allocation
        let inst = Object.create(Constr.prototype);

        // Initialization
        let result = Constr.apply(inst, args);
        if (result !== null &amp;amp;&amp;amp; typeof result === 'object') {
            return result;
        } else {
            return inst;
        }
    }
&lt;/pre&gt;
&lt;tt&gt;Array&lt;/tt&gt; overrides this method to allocate an exotic object.
&lt;p&gt;
&lt;b&gt;Eliminating the allocation obstacle.&lt;/b&gt; In a subtype of &lt;tt&gt;Array&lt;/tt&gt;, we’d like to reuse method &lt;tt&gt;[[Construct]]&lt;/tt&gt; of &lt;tt&gt;Array&lt;/tt&gt;. In ECMAScript 5, we can’t, because the prototype of a constructor is always &lt;tt&gt;Function.prototype&lt;/tt&gt; and never its super-constructor. That is, it doesn’t inherit &lt;tt&gt;[[Construct]]&lt;/tt&gt; from its super-constructor. However, in ECMAScript 6, constructor inheritance is the default.
&lt;p&gt;
Additionally, Wirfs-Brock proposes to handle allocation in a separate, publicly accessible method whose key is the well-known symbol &lt;tt&gt;@@create&lt;/tt&gt; (that can be imported from some module). &lt;tt&gt;Array&lt;/tt&gt; would only override that method and default &lt;tt&gt;[[Construct]]&lt;/tt&gt; would look like this for all constructors:
&lt;pre&gt;
    Function.prototype.[[Construct]] = function (...args) {
        let Constr = this;

        // Allocation
        let create = Constr[@@create] || Object[@@create];
        let inst = create();

        // Initialization
        let result = Constr.apply(inst, args);
        if (result !== null &amp;amp;&amp;amp; typeof result === 'object') {
            return result;
        } else {
            return inst;
        }
    }
&lt;/pre&gt;
Many builtins would have custom &lt;tt&gt;@@create&lt;/tt&gt; methods: &lt;tt&gt;Array&lt;/tt&gt;, &lt;tt&gt;String&lt;/tt&gt;, &lt;tt&gt;Boolean&lt;/tt&gt;, &lt;tt&gt;Number&lt;/tt&gt;, &lt;tt&gt;Date&lt;/tt&gt;, &lt;tt&gt;RegExp&lt;/tt&gt;, &lt;tt&gt;Map&lt;/tt&gt;, &lt;tt&gt;Set&lt;/tt&gt;, &lt;tt&gt;Weakmap&lt;/tt&gt;, &lt;tt&gt;ArrayBuffer&lt;/tt&gt;, ...
These builtins have exotic instances and/or custom values for the internal property &lt;tt&gt;[[Class]]&lt;/tt&gt; &lt;a class="ptr"&gt;[3]&lt;/a&gt;.
&lt;p&gt;
&lt;b&gt;Eliminating the initialization obstacle.&lt;/b&gt; Sub-constructors need to be able to use &lt;tt&gt;Array&lt;/tt&gt; for initialization. Thus, it needs to distinguish two different kinds of invocation:
&lt;ul&gt;
    &lt;li&gt;Used as a function: create a new instance.
    &lt;/li&gt;
    &lt;li&gt;Used for initialization (via &lt;tt&gt;new&lt;/tt&gt; or via a super-call): set up &lt;tt&gt;this&lt;/tt&gt;.
    &lt;/li&gt;
&lt;/ul&gt;
This is more tricky than it seems (and not something you should do for your own constructors). You might try the following:
&lt;pre&gt;
    function Foo() {
        'use strict';
        if (this === undefined) {  // (*)
            // Invoked as a function
        } else {
            // Invoked for initialization
        }
    }
&lt;/pre&gt;
However, this fails if you put &lt;tt&gt;Foo&lt;/tt&gt; into a namespace object:
&lt;pre&gt;
    var namespace = {};
    namespace.Foo = Foo;
    namespace.Foo();   // not treated as a function call
&lt;/pre&gt;
In line (*), you need to ensure that &lt;tt&gt;this&lt;/tt&gt; is not an instance of &lt;tt&gt;Foo&lt;/tt&gt;:
&lt;pre&gt;
    if (this === undefined || !(this instanceof Foo)) ...
&lt;/pre&gt;
You could also trigger the “function” case for instances of &lt;tt&gt;Foo&lt;/tt&gt; that have already been initialized.
&lt;p&gt;
This solution will probably be adopted by ECMAScript 6. Its complexity will be largely hidden: You can either use the canonical way of subtyping shown above or you can use a class definition:
&lt;pre&gt;
    class MyArray extends Array {
        ...
    }
&lt;/pre&gt;

&lt;h3&gt;When &lt;tt&gt;new&lt;/tt&gt; does not initialize&lt;/h3&gt;

The following problem is independent of the “function versus initialization” problem mentioned in Sect. 2.3: Some constructors, even when invoked directly via &lt;tt&gt;new&lt;/tt&gt;, don’t initialize the instance that has been created, they throw it away. The following subsections describe when that happens.

&lt;h4&gt;Factory constructors&lt;/h4&gt;

&lt;b&gt;Use case.&lt;/b&gt; A factory constructor is “abstract”: it examines its arguments and, depending on their values, invokes one of its sub-constructors. Many class-based languages use static factory methods for this purpose.
&lt;p&gt;
&lt;b&gt;Solution.&lt;/b&gt; You need to distinguish whether you are called directly via &lt;tt&gt;new&lt;/tt&gt; or via a sub-constructor. It is conceivable to add language support for this. An alternative is to have a parameter &lt;tt&gt;calledFromSubConstructor&lt;/tt&gt; whose default value is &lt;tt&gt;false&lt;/tt&gt;. Sub-constructor set it to &lt;tt&gt;true&lt;/tt&gt;. If it is &lt;tt&gt;true&lt;/tt&gt;, you initialize. Otherwise, you return the result of a sub-constructor.

&lt;h4&gt;Cached instances&lt;/h4&gt;

This use case is very similar to factory constructors. For example, constructor might put every instance it creates in a cache. If it is told to create an instance that is similar to one in the cache, it returns the cached one, instead. The solution is the same as for factory constructors. However, if you subtype, more work is probably needed, especially if the subtype has a different notion of similarity.

&lt;h4&gt;Returning an argument&lt;/h4&gt;

Some constructors return their argument if it fulfills certain criteria. For example, &lt;tt&gt;Object&lt;/tt&gt;:
&lt;pre&gt;
    &amp;gt; var obj = {};
    &amp;gt; new Object(obj) === obj
    true
&lt;/pre&gt;
Again, this can be solved in the manner described in Sect. 3.1.

&lt;h3&gt;A few observations&lt;/h3&gt;

&lt;h4&gt;The constructor as a method&lt;/h4&gt;

In ECMAScript 6, the role of the constructor as a method that initializes an object increases.
Take, for example, the following line from the &lt;tt&gt;[[Construct]]&lt;/tt&gt; method:
&lt;pre&gt;
    let result = Constr.apply(inst, args);
&lt;/pre&gt;
It is equivalent to:
&lt;pre&gt;
    let result = inst.constructor(...args);
&lt;/pre&gt;
Furthermore, sub-constructors call super-constructors to help them with initialization. For example:
&lt;pre&gt;
    function SubConstr(arg1, arg2) {
        super.constructor(arg1);  // or: super(arg1)
    }
&lt;/pre&gt;
Lastly, even though a class is internally translated to a constructor, the actual constructor body is inside a method:
&lt;pre&gt;
    class MyClass {
        constructor(...) {
            ...
        }
        ...
    }
&lt;/pre&gt;

&lt;h4&gt;JavaScript becomes less prototypal&lt;/h4&gt;

With constructors handling allocation via &lt;tt&gt;@@create&lt;/tt&gt;, you can’t use the prototype to create an instance, any more:
&lt;pre&gt;
    let inst = Object.create(MyConstr.proto);
    inst.constructor(arg1, arg2);
&lt;/pre&gt;
Instead, you have to do the following.
&lt;pre&gt;
    let inst = MyConstr[@@create]();
    inst.constructor(arg1, arg2);
&lt;/pre&gt;

&lt;h4&gt;A method for post-initialization?&lt;/h4&gt;

One could introduce &lt;tt&gt;@@postConstruct&lt;/tt&gt;, a method that is invoked after all constructors have been executed. It is the inverse of &lt;tt&gt;@@create&lt;/tt&gt;. Use case for this method: &lt;a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/freeze"&gt;freeze&lt;/a&gt; an instance or make it &lt;a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/preventExtensions"&gt;non-extensible&lt;/a&gt;.

&lt;h4&gt;How about ECMAScript 5?&lt;/h4&gt;

There are a few tricks you can use to subtype builtins in ECMAScript 5 &lt;a class="ptr"&gt;[4]&lt;/a&gt;.

&lt;h4&gt;Acknowledgement&lt;/h4&gt;

Thanks to Allen Wirfs-Brock for answering my questions about his slides.

&lt;h3&gt;References&lt;/h3&gt;

&lt;ol id="references"&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2011/06/constructor-property.html"&gt;What’s up with the “constructor” property in JavaScript?&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2012/10/proto.html"&gt;JavaScript: __proto__&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2013/01/categorizing-values.html"&gt;Categorizing values in JavaScript&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www.2ality.com/2011/12/subtyping-builtins.html"&gt;Subtyping JavaScript builtins in ECMAScript 5&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;img src="http://feeds.feedburner.com/~r/2ality/~4/eG5P8waNlMg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.2ality.com/feeds/5859166833396397490/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=8100407163665430627&amp;postID=5859166833396397490" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/5859166833396397490?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8100407163665430627/posts/default/5859166833396397490?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/2ality/~3/eG5P8waNlMg/subclassing-builtins-es6.html" title="Subclassing builtins in ECMAScript 6" /><author><name>Axel Rauschmayer</name><uri>https://plus.google.com/110516491705475800224</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-Co_34CwBCQU/AAAAAAAAAAI/AAAAAAAAAuM/VlxolpljJ4s/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.2ality.com/2013/03/subclassing-builtins-es6.html</feedburner:origLink></entry></feed>
