{"id":778,"date":"2017-08-31T14:45:37","date_gmt":"2017-08-31T22:45:37","guid":{"rendered":"http:\/\/www.wirfs-brock.com\/allen\/?p=778"},"modified":"2018-10-04T15:58:43","modified_gmt":"2018-10-04T23:58:43","slug":"some-ecmascript-explanations-and-stories-for-dave","status":"publish","type":"post","link":"https:\/\/wirfs-brock.com\/allen\/posts\/778","title":{"rendered":"Some ECMAScript Explanations and Stories for Dave"},"content":{"rendered":"<p><a href=\"http:\/\/www.wirfs-brock.com\/allen\/posts\/778\/ecs6cover_\" rel=\"attachment wp-att-779\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright wp-image-779 size-medium\" src=\"http:\/\/www.wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/ECS6cover_-219x300.jpg\" alt=\"\" width=\"219\" height=\"300\" srcset=\"https:\/\/wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/ECS6cover_-219x300.jpg 219w, https:\/\/wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/ECS6cover_.jpg 353w\" sizes=\"(max-width: 219px) 100vw, 219px\" \/><\/a>Dave Winer <a href=\"http:\/\/scripting.com\/2017\/08\/30.html#a111437\">recently blogged<\/a> about his initial thoughts after dipping his toes into using some modern JavaScript features . He ends by suggesting that I might have some\u00a0 explanations and stories about the features he are using.\u00a0 I\u2019ve given <a href=\"http:\/\/www.wirfs-brock.com\/allen\/things\/interviews-and-chats\">talks<\/a> that cover some of this and normally I might just respond via some terse tweets. But Dave believes that blog posts should be responded to by blog posts so I&#8217;m taking a try at blogging back to him.<\/p>\n<div id=\"WhatToCallIt\"><\/div>\n<h2><a href=\"#WhatToCallIt\" target=\"_top\">What To Call It?<\/a><\/h2>\n<p>The JavaScript language is defined by a specification maintained by the <a href=\"https:\/\/www.ecma-international.org\/\">Ecma International<\/a> standards organization. Because of trademark issues, dating back to 1996, the specification could not use the name JavaScript.\u00a0 So they coined the name ECMAScript instead. Contrary to some myths, ECMAScript and JavaScript are not different languages. \u201cECMAScript&#8221; is simply the name used within the specification where it would really like to say \u201cJavaScript\u201d.<\/p>\n<p>Standards organizations like to identify documents using numbers. The ECMAScript specification\u2019s number is ECMA-262.\u00a0 Each time an update to the specification is approved as \u201cthe standard&#8221; a new edition of ECMA-262 is released. Editions are sequentially numbered. Dave said &#8220;ES6 is the newest version of JavaScript\u201d.\u00a0 So, what is \u201cES6\u201d? ES6 is colloquial shorthand for \u201cECMA-262, Edition 6\u201d.\u00a0 ES6 was published as a standard in 2015. The actual title of the ES6 specification is <em>ECMAScript 2015 Language Specification<\/em> and the preferred shorthand name is ECMAScript 2015 or just ES2015.<\/p>\n<p>So, why the year-based designation?\u00a0 The 6th edition of ECMA-262 took a long time to develop, arguably 15 years. As ES6 was approaching publication, <a href=\"https:\/\/github.com\/tc39\">TC39<\/a> (the Technical Committee within Ecma International that develops the ECMAScript specifications) already knew that it wanted to change its process in a way that enabled\u00a0 yearly maintenance updates.\u00a0 That meant a new edition of ECMA-262 every year with a new edition number. After a few years we would be talking about ES6, ES7, ES8, ES9, ES10, ES11, etc. Those numbers quickly loose any context for people who aren\u2019t deeply involved in the standards development process. Who would know if the current standard ES7, or ES8, or ES9? Was some feature introduced in ES6 or ES7? TC39 couldn\u2019t eliminate the actual edition numbers (standards organizations love their document numbers) but it could change the document title.\u00a0 We decide that TC39 would incorporate the year of release into the documents title and to encourage people to use the year when referring to a specific edition. So, the \u201cnewest version of JavaScript\u201d is ECMA-262, Edition 8 and its title is\u00a0 <em>ECMAScript 2017 Language Specification<\/em>. Some people still refer to it as ES8, but the preferred shorthand name is ECMAScript 2017 or just ES2017.<\/p>\n<p>But saying \u201cECMAScript\u201d or mentioning specific ECMAScript editions is confusing to many people and probably is unnecessary for most situations.\u00a0 The common name of the language really is JavaScript and unless you are talking about the actual specification document you probably don\u2019t need to utter \u201cECMAScript\u201d. But you may need to distinguish between old versions of JavaScript and what is implemented by newer, modern implementations.\u00a0 The big change in the language and its specification occurred with\u00a0 ES2015.\u00a0 The subsequent editions make relatively small incremental extensions and corrections to what was standardized in 2015.\u00a0 So, here is my recommendation.\u00a0 Generally you should\u00a0 just say \u201cJavaScript\u201d meaning the language as it is used in browsers, Node.js, and other environments.\u00a0 If you need to specifically talk about JavaScript implementations that are based upon ECMAScript specifications published prior to ES2015 say \u201clegacy JavaScript\u201d. If you need to specifically talk about JavaScript that includes ES2015 (or later) features say \u201cmodern JavaScript\u201d.<\/p>\n<div id=\"canyouuseit\"><\/div>\n<h2><a href=\"#canyouuseit\">Can You Use It Yet?<\/a><\/h2>\n<p>Except for modules almost all of ES2015-ES2017 is <a href=\"https:\/\/kangax.github.io\/compat-table\/es6\/\">implemented in the current versions<\/a> of all the major <a href=\"https:\/\/www.techopedia.com\/definition\/31094\/evergreen-browser\">evergreen browsers<\/a> (Chrome, Firefox, Safari, Edge). Also <a href=\"http:\/\/node.green\/\">in current versions of Node.js<\/a>. If you need to write code that will run on non-evergreen browsers such as IE you can use <a href=\"https:\/\/babeljs.io\/\">Babel<\/a> to pre-compile modern JavaScript code into legacy JavaScript code.<\/p>\n<p>Module support <a href=\"https:\/\/caniuse.com\/#search=es6-module\">exists in all of the evergreen browsers<\/a>, but some of them still require setting a flag to use it.\u00a0 Native ECMAScript module support will hopefully ship in Node.js in spring 2018. In the meantime <a href=\"https:\/\/blogs.windows.com\/msedgedev\/2017\/08\/10\/es-modules-node-today\/\">@std\/esm<\/a> enables use of ECMAScript modules in current Node releases.<\/p>\n<div id=\"BlockScoping\"><\/div>\n<h2><a href=\"#BlockScoping\"> Scoped Declaration (let and const)<\/a><\/h2>\n<p>The main motivation for block scoped declarations was to eliminate the &#8220;closure in loop\u201d bug hazard that may JavaScript programmer have encountered when they set event handlers within a loop. The problem is that <strong>var<\/strong> declarations look like they should be local to the loop body but in fact are hoisted to the top of the current function and hence each event handler defined in the loop use the last value assigned to such variables.<br \/>\n<a href=\"http:\/\/www.wirfs-brock.com\/allen\/posts\/778\/closure-in-loop\" rel=\"attachment wp-att-780\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-780\" src=\"http:\/\/www.wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/closure-in-loop-300x170.jpg\" alt=\"\" width=\"512\" height=\"290\" srcset=\"https:\/\/wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/closure-in-loop-300x170.jpg 300w, https:\/\/wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/closure-in-loop-768x435.jpg 768w, https:\/\/wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/closure-in-loop-1024x581.jpg 1024w, https:\/\/wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/closure-in-loop.jpg 1785w\" sizes=\"(max-width: 512px) 100vw, 512px\" \/><\/a><\/p>\n<p>Replacing <strong>var<\/strong> with <strong>let<\/strong> gives each iteration of the loop a distinct variable binding.\u00a0 So each event handler captures different variables with the values that were current when the event handler was installed:<\/p>\n<a href=\"http:\/\/www.wirfs-brock.com\/allen\/posts\/778\/fix-closure-in-loop\" rel=\"attachment wp-att-781\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-781\" src=\"http:\/\/www.wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/fix-closure-in-loop-1024x561.jpg\" alt=\"\" width=\"512\" height=\"281\" srcset=\"https:\/\/wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/fix-closure-in-loop-1024x561.jpg 1024w, https:\/\/wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/fix-closure-in-loop-300x164.jpg 300w, https:\/\/wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/fix-closure-in-loop-768x421.jpg 768w, https:\/\/wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/fix-closure-in-loop.jpg 1843w\" sizes=\"(max-width: 512px) 100vw, 512px\" \/><\/a>\n<p>The hardest part about adding block scoped declaration to ECMAScript was coming up with a rational set of rules for how the declaration\u00a0 should interact with the already existing <strong>var<\/strong> declaration form. We could not change the semantics of <strong>var<\/strong> without breaking backwards compatibility, which is something we try to never do. But, we didn\u2019t want to introduce new WTF surprises in programs that use both <strong>var<\/strong> and <strong>let<\/strong>. Here are the basic rules we eventually arrived at:<\/p>\n<div id=\"es6-dcl-rules\"><\/div>\n<p><a href=\"#es6-dcl-rules\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-782\" src=\"http:\/\/www.wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/ES6-dcl-rules-1024x601.jpg\" alt=\"\" width=\"512\" height=\"301\" srcset=\"https:\/\/wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/ES6-dcl-rules-1024x601.jpg 1024w, https:\/\/wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/ES6-dcl-rules-300x176.jpg 300w, https:\/\/wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/ES6-dcl-rules-768x451.jpg 768w, https:\/\/wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/ES6-dcl-rules-1200x705.jpg 1200w, https:\/\/wirfs-brock.com\/allen\/wp-content\/uploads\/2017\/08\/ES6-dcl-rules.jpg 1408w\" sizes=\"(max-width: 512px) 100vw, 512px\" \/><\/a><br \/>\nMost browsers, except for IE, had implemented <strong>const<\/strong> declarations (but without block scoping) starting in the early naughts. Firefox implemented block scoped <strong>let<\/strong> declaration (but not exactly the same semantics as ES2015) in 2006.\u00a0 By the time TC39 started serious working on what ultimately became ES2015, the keywords <strong>const<\/strong> and <strong>let<\/strong> had become ingrained in our minds such that we didn\u2019t really consider any other alternatives. I regret that.\u00a0 In retrospect, I think we should have used <strong>let<\/strong> in place of\u00a0 <strong>const<\/strong> for declaring immutable variable bindings because that is the most common use case. In fact, I&#8217;m pretty sure that many developers use <strong>let<\/strong>\u00a0instead of <strong>const<\/strong> for variable they don&#8217;t intend to change, simply because <strong>let<\/strong> has fewer characters to type. If we had used <strong>let<\/strong> in place of <strong>const<\/strong> then perhaps <strong>var<\/strong> would have been adequate for the relatively rare cases where a mutable variable binding is needed.\u00a0 A language with only <strong>let<\/strong> and <strong>var<\/strong> would have been simpler then what we ended up with using <strong>const<\/strong>, <strong>let<\/strong>, and <strong>var<\/strong>.<\/p>\n<div id=\"Arrows\"><\/div>\n<h2><a href=\"#Arrows\">Arrow Functions<\/a><\/h2>\n<p>One of the primary motivations for arrow functions was to eliminate another JavaScript bug hazard.\u00a0 The \u201cwrong this&#8221; problem that occurs when you capture a function expression (for example, as an event handler) but forget that <strong>this<\/strong> used inside the function expression will not be the same value as <strong>this<\/strong> in the context where you created the function expression.\u00a0 Conciseness was a consideration in the design of arrow functions, but fixing the \u201cwrong this\u201d problem was the real driver.<\/p>\n<p>I\u2019ve heard several JS programmers comment that at first they didn\u2019t like arrow functions but that they grew upon them over time. Your mileage may vary. Here are a couple of good articles that <a href=\"https:\/\/www.raymondcamden.com\/2017\/08\/25\/why-i-hated-and-now-love-arrow-functions\/\">address<\/a> arrow function <a href=\"https:\/\/medium.com\/javascript-scene\/familiarity-bias-is-holding-you-back-its-time-to-embrace-arrow-functions-3d37e1a9bb75)\">reluctance<\/a>.<\/p>\n<div id=\"Modules\"><\/div>\n<h2><a href=\"#Modules\">Modules<\/a><\/h2>\n<p>Actually, ES modules weren\u2019t inspired by Node modules. But a lot of work went into making them <a href=\"http:\/\/jsmodules.io\/cjs.html\">feel familiar<\/a>\u00a0 to people who were used to Node modules. In fact,\u00a0 ES modules are semantically more similar to the Pascal modules that Dave remembers then they are to Node modules.\u00a0 The big difference is that in the ES design (and Pascal modules) the interfaces between modules are statically defined while in the Node modules design\u00a0 module interfaces are dynamically defined. With static module interfaces the inter-dependencies between a set of modules are precisely defined by the source code prior to executing any code.\u00a0 With dynamic modules, the module interfaces cannot be fully understood without actually executing the code of the modules.\u00a0 Or stated another way, ES module interfaces are declaratively defined while Node module interfaces are imperatively defined. Static modules systems better support creation of ahead-of-time tools such as accurate module dependency linters or module linkers. Such tools for dynamic module interfaces usually depends upon applying heuristics that analyze modules as if they had static interfaces.\u00a0 Such analysis can be wrong if the actual dynamically\u00a0 interfaces construction does things that the heuristics didn\u2019t account for.<\/p>\n<p>The work on the ES module design actually started before the first release of Node. There were early proposals for dynamic module interfaces that are more like what Node adopted.\u00a0 But TC39 made an early decision that declarative static module interfaces were a better design, for the long term. There has been much controversy about this decision. Unfortunately, it\u00a0has created issues for Node which have been difficult for them to resolve. If TC39 had anticipated the rapid adoption of Node and the long time it would take to finish \u201cES6\u201d we might have taken the dynamic module interface path. I\u2019m glad we didn\u2019t and I think it is becoming clear that we made the right choice.<\/p>\n<div id=\"Promises\"><\/div>\n<h2><a href=\"#Promises\">Promises<\/a><\/h2>\n<p>Strictly speaking, the legacy JavaScript language didn\u2019t do async at all.\u00a0 It was host environments such as\u00a0 browsers and Node that defined the APIs that introduced async programming into JavaScript.<\/p>\n<p>ES2015 needed to include promises because they were being rapidly adopted by the developer community (include by new browser APIs) and we wanted to avoid the problem of competing incompatible promise libraries or of a browser defined promise API that didn\u2019t take other host environments into consideration.<\/p>\n<p>The real benefit of ES2015 promises is that they provided a foundation for better async abstractions that do bury more of the BS within the runtime.\u00a0 <a href=\"https:\/\/developers.google.com\/web\/fundamentals\/getting-started\/primers\/async-functions\">Async functions<\/a>, introduced in ES2017 are the \u201cbetter way\u201d to do async.\u00a0 In the pipeline for the near future is <a href=\"https:\/\/jakearchibald.com\/2017\/async-iterators-and-generators\/\">Async Iteration<\/a> which further simplifies a common async use case.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dave Winer recently blogged about his initial thoughts after dipping his toes into using some modern JavaScript features . He ends by suggesting that I might have some\u00a0 explanations and stories about the features he are using.\u00a0 I\u2019ve given talks that cover some of this and normally I might just respond via some terse tweets. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,6,8],"tags":[],"_links":{"self":[{"href":"https:\/\/wirfs-brock.com\/allen\/wp-json\/wp\/v2\/posts\/778"}],"collection":[{"href":"https:\/\/wirfs-brock.com\/allen\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wirfs-brock.com\/allen\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wirfs-brock.com\/allen\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wirfs-brock.com\/allen\/wp-json\/wp\/v2\/comments?post=778"}],"version-history":[{"count":30,"href":"https:\/\/wirfs-brock.com\/allen\/wp-json\/wp\/v2\/posts\/778\/revisions"}],"predecessor-version":[{"id":844,"href":"https:\/\/wirfs-brock.com\/allen\/wp-json\/wp\/v2\/posts\/778\/revisions\/844"}],"wp:attachment":[{"href":"https:\/\/wirfs-brock.com\/allen\/wp-json\/wp\/v2\/media?parent=778"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wirfs-brock.com\/allen\/wp-json\/wp\/v2\/categories?post=778"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wirfs-brock.com\/allen\/wp-json\/wp\/v2\/tags?post=778"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}