ES2019 features coming to JavaScript (starring us!)
Shape Security has been contributing actively to TC39 and other standards bodies for the past 4 years but this year is special for us. A significant portion of the features coming to JavaScript as part of the 2019 update are from Shape Security engineers! Shape contributes to standards bodies to ensure new features are added while taking into account evolving security implications. Anything Shape contributes outside of this broad goal is because we believe the web platform is the greatest platform ever made and we want to help it grow even better.
TL;DR
The 2019 update includes quality-of-life updates to JavaScript natives, and standardizes undefined or inconsistent behavior.
Buffed: String, Array, Object, Symbol, JSON
Nerfed: Try/Catch
Adjusted: Array.prototype.sort, Function.prototype.toString
Native API additions
Array.prototype.flat & .flatMap
> [ [1], [1, 2], [1, [2, [3] ] ] ].flat();< [1, 1, 2, 1, [2, 3]]> [ [1], [1, 2], [1, [2, [3] ] ] ].flat(2);< [1, 1, 2, 1, 2, 3]
The Array prototype methods flat
and flatMap
got unexpected attention this year, not because of their implementation, but because Shape Security engineer Michael Ficarra opened a gag pull request renaming the original method flatten
to smoosh
thus starting SmooshGate. Michael opened the pull request as a joke after long TC39 meetings on the topic and it ended up giving the average developer great insight into how TC39 works and under how big of a microscope proposals are placed under. When considering new features to add to JavaScript, the TC39 committee has to take two decades of existing websites and applications into account to ensure no new feature unexpectedly breaks them.
After FireFox shipped flatten
in the nightly releases, users found that websites using the MooTools framework were breaking. MooTools had added flatten
to the Array prototype ten years ago and now any site using MooTools risks breaking if the method changes. Since MooTools usage has declined in favor of more modern frameworks, many sites using the library are sites which are no longer actively maintained — they will not be updated even if MooTools released an updated version. SmooshGate ended up surfacing serious discussions as to what degree existing websites affect future and present innovation.
The committee concluded backwards compatibility was of higher importance and renamed the method flatten
to flat
. It’s a long, complicated story with an anticlimactic ending but that could be said of all specification work.
Drama aside, flat operates on an array and “flattens” nested arrays within to a configurable depth. flatMap operates similarly to the map method by applying a function to each element in the list and then calling flat() on the resulting list.
Object.fromEntries
let obj = { a: 1, b: 2 };let entries = Object.entries(obj);let newObj = Object.fromEntries(entries);
Object.fromEntries
is a complement to the Object.entries
method which allows a developer to more succinctly translate objects from one another. Object.entries
takes a regular JavaScript object and returns a list of [key, value]
pairs, Object.fromEntries
enables the reverse.
String.prototype.trimStart & .trimEnd
> ' hello world '.trimStart()< "hello world "> ' hello world '.trimEnd()< " hello world"
Major JavaScript engines had implementations of String.prototype.trimLeft()
and String.prototype.trimRight()
but the methods lacked a true definition in the spec. This proposal standardizes the names as trimStart
and trimEnd
, aligning terminology with padStart
and padEnd
, and aliases trimLeft
and trimRight
to the respective function.
Symbol.prototype.description
> let mySymbol = Symbol('my description');< undefined> mySymbol.description< 'my description'
Symbol.prototype.description
is an accessor for the unexposed description
property. Before this addition, the only way to access the description passed into the constructor was by converting the Symbol to a string via toString()
and there was no intuitive way to differentiate between Symbol()
and Symbol(‘’)
.
Spec & Language Cleanup
Try/Catch optional binding
try { throw new Error();} catch { console.log('I have no error')}
Until this proposal, omitting the binding on catch resulted in an error when parsing the JavaScript source text. This resulted in developers putting in a dummy binding despite them being unnecessary and unused. This is another quality-of-life addition allowing developers to be more intentional when they ignore errors, improving the developer experience and reducing cognitive overhead for future maintainers.
Make ECMAScript a proper superset of JSON
JSON.parse
describes JSON as a subset of JavaScript despite valid JSON including Unicode line separators and paragraph separators not being valid JavaScript. This proposal modifies the ECMAScript specification to allow those characters in string literals. The majority of developers will never encounter this usage but it reduces edge case handling for developers dealing with the go-between and generation of JavaScript and JSON. Now you can insert any valid JSON into a JavaScript program without accounting for edge cases in a preprocessing stage.
Well-formed JSON.stringify
> JSON.stringify('\uD834\uDF06')< "\"𝌆\""> JSON.stringify('\uDF06\uD834')< "\"\\udf06\\ud834\""
This proposal rectifies inconsistencies in description and behavior for JSON.stringify
. The ECMAScript spec describes JSON.stringify
as returning a UTF-16 encoded JSON format string but can return values that are invalid UTF-16 and are unrepresentable in UTF-8 (specifically surrogates in the Unicode range U+D800
—U+DFFF
). The accepted resolution is, when encoding lone surrogates, to return the code point as a Unicode escape sequence.
Stable Array.prototype.sort()
This is a change to the spec reflecting the behavior standardized by practice in major JavaScript engines. Array.prototype.sort
is now required to be stable — values comparing as equal stay in their original order.
Revised Function.prototype.toString()
The proposal to revise Function.prototype.toString
has been a work-in-progress for over 3 years and was another proposed and championed by Michael Ficarra due to problems and inconsistencies with the existing spec. This revision clarifies and standardizes what source text toString()
should return or generate for functions defined in all the different forms. For functions created from parsed ECMAScript source, toString()
will preserve the whole source text including whitespace, comments, everything.
Onward and upward
ES2015 was a big step for JavaScript with massive new changes and, because of the problems associated with a large change set, the TC39 members agreed it is more sustainable to produce smaller, yearly updates. Most of the features above are already implemented in major JavaScript engines and can be used today.
If you are interested in reading more TC39 proposals, including dozens which are in early stages, the committee makes its work available publicly on Github.com. Take a look at some of the more interesting proposals like the pipeline operator and optional chaining.
*** This is a Security Bloggers Network syndicated blog from Shape Security Blog authored by jsoverson. Read the original post at: https://blog.shapesecurity.com/2019/02/12/es2019-features-coming-to-javascript-starring-us/