NAMING THE STANDARD
ANOTHER YEAR => ANOTHER VERSION
Though ECMA International now releases a new version every year, this wasn’t always the case. With the first version of the ECMA standard being adopted by the ECMA General Assembly in June of 1997, we had sporadic (albeit necessary) updates to the language up until ES6 (ES2015), which provided a whole slew of additions that have become synonymous with the language, including fan favorites: Arrow Functions, Template Literals (my favorite), and the variable declarations const and let, to name a few.
Before getting to the new features of ES2019 and ES2020, I must preface that not every browser is compatible with the brand new additions laid out below (especially the ES2020 ones), as it’s up to the individual companies to update their own engines. Remember to check the browser compatibility on our favorite resource, MDN web docs for any conflicts.
Alright, now let's focus on the real reason why you’re here, to learn cool new tips and tricks that will take your engineering to the next level! We’ll start with the ES2019 additions:
The flat method creates a new array with all sub-array elements concatenated into it, up to the depth which you specify as an optional argument. When no argument is passed, the depth defaults to 1. Before this addition, you could go about flattening an array a variety of ways. However, most were complicated, clunky, and verbose, here’s an example:
Now we have a built-in method that takes a recursive approach under the hood. Let’s see it in action:
Ahh yes, much better. Clean, concise, and beautiful! Let’s move on.
As you may have guessed, .flatMap() is a combination of the native .map() method with the new .flat() method, which first maps each element, then flattens to the depth of 1 and returns a new array. While this is identical to using .map() followed by .flat(), combining the two becomes slightly more performant, and of course, easier to read:
I personally love this one. Object.fromEntries() will change the list of key-value pairs of an iterable, such as an Array or Map (or other objects implementing the iterable protocol) into an Object:
Object.fromEntries() is also the inverse of the Object.entries() method:
String.prototype.trimStart() and String.prototype.trimEnd()
Now, you may be saying, “…but Matt, there are already methods to do this called .trimRight() and .trimLeft(),” and that’s absolutely correct, but ES2019 added .trimStart() and .trimEnd() so the method names can be more in line with their purposes (.trimRight() and .trimLeft() will remain aliases for .trimStart() and .trimEnd() respectively for web browser compatibility):
ES2019 - UPDATED SYNTAX
Optional Catch Binding
Before ES2019, we were required to make an argument in a catch block, without one we get a ‘Syntax Error.’ However, there were times when this binding wouldn't be used, especially when you want your catch statement to do something that doesn’t care about the value that’s thrown:
Now, you can simply leave off the parentheses and it’s smooth sailing:
ES2019 - UNDER-THE-HOOD IMPROVEMENTS
Array.prototype.sort() is now a stable sort
Fun fact, TimSort was created by Tim Peters (no relation…) in 2002 for use in Python, and was designed to perform well with many kinds of real-world data (Pythons claim to fame). With a best-case time complexity of O(n), an average and worst-case time complexity of O(n log n), it slightly edges out MergeSort who’s best, average, and worst-case complexities are a consistent O(n log n). Very cool!
Now it’s time for the brand new ECMAScript 2020 (11th edition) features. While the 2019 features are certainly nice, the 2020 additions listed below are really exciting! Bear in mind, these are bleeding-edge and have not fully reached cross-browser stability. An example being Nullish Coalescing mentioned below, which is supported in the latest version of Chrome and only for Node.js 14.0.0+. It does not work for Internet Explorer (big surprise there...) or the mobile versions of Firefox, Opera, and Samsung Internet as of this writing. However, that’s not going to stop us from checking them out.
Who loves regular expressions? **cricket cricket**
Well… we now have a method that matches a string against a regular expression, and returns an iterator of all the resulting matches:
You’ll notice I included the global (‘/g’) flag in my RegEx example. This is actually required for the regular expression you’re testing against (which makes sense, as you’re searching for ALL occurrences!), otherwise, a TypeError will be thrown. So be vigilant!
Hmm, looks like we’ve hit our max. Until now!
With the normal Numbers object, we are unable to go above 90,071,99,254,740,992. Now with the BingInt data type, we can work with very large integers above this cap:
Now we have the option to check for values that are just nullish (undefined or null) instead of outright falsey (undefined, null, false, NaN, 0, ‘’), using the new nullish coalescing operator (‘??’) syntax:
Compare this to using the or (||) operator:
Now the and (&&) operator:
As you can see, when we only want to deal with logic involving null (**caugh BST’s and Linked Lists **caugh **caugh) or undefined, we now have a more explicit option for doing so.
The new optional chaining operator (‘?.’) allows us to read values nested within objects without having to validate each reference in the chain. Normally a reference error is thrown if your code has an erroneous path through object properties, as the reference would be nullish (meaning null or undefined). When that happens, it’s game over and your code won't run. Now, with the optional chaining operator, the thrown error is short-circuited and will simply return undefined. Let’s see it in action:
This one’s a, “Wow, this should have been implemented long ago,” addition. globalThis is a universal way to access the global 'this' value, no matter what platform you’re coding for. Now, no matter if you’re working in Node, the browser, or a web-worker, which all have different namespaces (‘global’, ‘window’ or ‘self’ respectfully), you’ll be able to access the global object with one universal property:
You’ll notice this example returns the Window object, as it was invoked within the console of my browser. If this were invoked within Node, you’d get Node’s respective global object!
Happy coding and thanks again!