JavaScript ES6 + ECMAScript History & Guide
By: Arnold Abraham
Tags: Technology, JavaScript, Education, Programming, Web Development

JavaScript ECMAScript History- The hidden treasures

JavaScript history guide about the hidden tricks in ECMAScript version

Introduction

JavaScript has changed over the years, that is a fact. And it has changed enormously during the last decade. A significant change brought ECMAScript2015, also known as ECMAScript6 (ES6). Since then, once a year a new ECMAScript has been released. But when most of you know the big changes, do you also know about the little things? The things that are also worthy to be looked at? In this article, I will introduce you to them.

ECMAScript 2016

Power of or **-Operator

This wasn’t a game changer, but it has its right to exist, because of its high practicability.

ECMA2016 made you able to use the power of love... I mean the shortest way ever to potentiate a number with another one. The power operator ** ensures that you can omit Math.Pow(a,b).

Before that, and if you come from C#, you know what has to be done here. Right, call Math.Pow(). This seems not like an impact at all, but if you do long mathematical calculations and every time in between the term, a function call comes up, then one already stopped over those function calls and have a short mental break.

Includes

This one brings a simplification for checking if an element exists inside an array. Most programmers and I did it as well, use the IndexOf() method, and use the return value to proceed with our operations. Also, the code gets more readable and more humanoid.

ATTENTIONBOX: Includes does only check for the value of the value type in order to return a correct result. When reference types like objects or arrays are used, then they are compared by their linking reference!

ECMAScript 2017

2017 was an exceptional year for JavaScript, whereas the big two words came onto the table: Async and Await. They revolutionized the way of writing asynchronous code. We rose from Callbacks and Promises to these new keywords. But wait! Aren’t async and await basing on callbacks and promises? Yes, they do, but they make the code at least readable like synchronous one, whereas callbacks and promises do not!

We are coming now back to the topic of why we are here. All the small things that aren’t honored on the big stage will get their graduation at mine. Since then, it is possible to add the last comma behind the last parameter of a function. This aligns with the rules of arrays and objects. That's just a minor thing, but more spectacular is the fact that you are able to use padStart/padEnd, to fill up strings for formatting reasons e.g. with spaces.

Console Print out for padStart (code: padding.js)

As you can see from the console print, I am filling up the penny prices with leading zeros to get my format right for e.g. a shop. If you send no second parameter to this function, it will fill up the leading chars with spaces.

I almost forgot to mention that there are two more functions that can come in quite handy. Object.values and Object.entries. They return the values or the key-value-pairs of an object as an array. Tip: In combination with a for-of loop, they are pretty tough!

ECMAScript 2018

2018 wasn’t such a highlighting year for JavaScript, but it brought us the Rest- and the Spread-operator being used on objects instead of arrays only. Another rising star was the introduction of the await-of-loop. It is the asynchronous antagonist of the for-of loop.

ECMAScript 2019

Try-Catch-don't care

Coming from C#? Then I think you know exceptions very well and you also have to specify which type of exception you want to catch or at least, declare the base type of all exceptions to make sure you handle them at least. ECMAScript2019 introduced Optional Catch Binding. You can just ignore the exception and return a value, that is more interesting to you.

CheckEquipment could be a function that returns a null if armor isn’t equipped. We want to know if a certain armor is equipped and you fear any exception? Whatever comes back, if it is not the armor you intentionally passed in, just return a false as the default value, and you are done! Quite simple, huh?

Flat

Another benefit of ECMAScript 2019 is the flat function. Used to get rid of nested arrays. Similar to the reduce function, but it can only reduce one level of nesting.

console print out after running items.flat().

The reduction of one level is no problem. Either you chain the calls of flat or you can just pass in an integer parameter equivalent of the number of levels you want to flat.

A good relative of the flat function is the flatMap-function. This is a combination of flat and map. Instead of giving you a list of lists as result, you can instantly get a flattened result. Here are some gamble bets and the permissible output if you bet now.

The same happens if you call both functions individually, but this would will reduce code and work.

FlatMap works a bit more efficient and can be taken in computation intense scenarios.

TrimStart & TrimEnd

Both are working like the introduced padStart and padEnd functions, but instead of filling up, they are trimming unwanted empty characters. We can see them as a special task force to the regular trim function and as a fast access method. In the game engine, Unity are also fast access methods to create Vectors in plain directions.

Vector2.up() => (0,1), Vector2.left() => (-1,0) etc.

Object.fromEntries vs Objects.entries

If you want to get every key-value of an object as an array, you use the Object.entries method, whereas Object.fromEntries converts an array back to an object. You can profit when you are working with functions like reduce, map, filter and you got an object to process further on. Use Object.entries and wrap an Object.fromEntries around that. Here, I show you what I mean by the example of an equipment-object for my favorite video game Dark Souls:

Console printout of object.entries wrapped by object.fromEntries

You can do this also with the weapon and trinket slots.

ECMAScript 2020

BigBang or BigInt?

JavaScript did only know the data type number with a precision of a double following the specification of IEEE-754. That's the reason why JavaScript can hold values like +0/-0 and also Infinity, including -Infinity. Also, the not allowed mathematical operation: Division by 0 is a valid operation and does not lead to an error.

Console printout division by zero in JavaScript

But this functionality has its limit. Whereas integers do not have the full 64bit size range, because of the internal handling as floating-point numbers, amounts to the absolute maximum of an integer

(2⁵³)-1 = 9007199254740992.

If you want to access this number, you can do it by accessing the constant value Number.MAX_SAFE_INTEGER [1].

Interestingly, you can add up onto the max attainable integer value in JavaScript. But the result is not distinguishable anymore if you want to add up 1 or 2. With >3 it is possible again.

Console print out from goldExploit.js

ECMAScript 2020 made it possible to get rid of this, by adding an “n” to a number or just use the BigInt function when you initializing the variable.

But Attention here. You can only calculate variables of type BigInt with other variables of type BigInt, otherwise, it will cause a runtime error. The worst of all errors!

An error by calculating two different number types (BIG_INT and number)

Not mixing up types here, and you can use them like normal integers. A division leads to a round down to the next integer. All other ones like +,-,*,/ and ** (power) and % (modulo) are all legally accepted and work like a charm. Also, comparing operators work as expected. The only exception is the “===” operator, this is not useable if you want to compare two numbers where the first one is of type BigInt and the second of type number. Compare with the unsafe “==” one is available. Don’t know the difference between “==” and “===” in detail? Best stack overflow post. [2]

Some functions can not cover this data type BigInt. Better look this up, before you use it headless. [3][4]

No more this.troublemaker

Do you have experience with this little troublemaker? When I came from C# this looked like a known keyword, but I felt so wrong. There are memes existing to this, not for any kind of reason.

Introducing lambda expressions and strict mode made this to a not so sharp weapon anymore. Because of the effort to write working code was lowered by those two.

What became more difficult is the fact of accessing global space. But who wants to access global space, anyway? Hmm… sometimes, sometimes there are scenarios when you need to.

Working inside a browser, you can access it via window and sometimes with self or frames or the last option this. Node.JS provides only global and this.

Times ago, it pretty common to use an auxiliary function:

Using this function means also not being able to use strict mode. Because of the definition of a function and not a method, you can’t define this inside any function anymore (Function is the same as Method, but a method is inside an object, whereas a function is outside, like this ownerless function on the right side of getGlobal). To make a workaround another auxiliary function came up:

This one returns, whatever results not in undefined. This return must be global space. ECMAScript 2020 made an introduction getting rid of these workarounds:

globalThis

Now the code can be shorter, more robust, and for coders the best measurable scale: Expressiveness of the code.

Import Code with a dynamic touch

If you develop software, always aim for modularization. JavaScript offers you the import and export keywords in order to create and use modules. Import had a flaw back then. It allowed you to only write it at the start of a file. This was necessary because the environment needs to check which references are mandatory for importing and exporting.

When you do a plug-in based solution, it's mandatory to analyze the needed plugins during runtime, because they do not arise until runtime. The usage of require was a workaround and made it technically possible to dynamically load modules during runtime, but it left a code smell every time used. Version 2020 brought us a better working import. The import-function. Since then, there is now an import-function, can be called anywhere and enables dynamic loading, whereas the keyword import is only to be allowed at the top of a file. The module then is loaded onto asynchronously. In order to access this module, fulfill this promise by yourself, or use the await keyword.

Take it, hold it, love it!

Since the dynamic type system is older than the internet itself, there is a tradition to check if a variable, a parameter, or a property of an object is defined at all. After checking that, you set it normally to a default value. Mostly an If-check wins the race to find out, whether these are equal to undefined. Results in this into true, a default value will be assigned to the variable, parameter, or property.

What does exist to make this better? Falsy Values! These are values, that result in the logical condition result of false. In combination with the Or-Operator (||) you can use them as a fallback.

This seems to be much better, but the effect won’t last long, because this also changed the semantic. GetNearestEnemy() will be called, not only when the enemy is undefined but also when the enemy is null, 0, false, or an empty string. These are 4 options, and if some of them might not occur here, there is always a matching for at least two of them, resulting in the alternative after the Or-Operator. It depends on which type of variable you use. If you want to use a number, you could make it this way:

The function is now safe against the input of 0. You will make every time damage. 0 Damage is not possible. If you want to enable 0 damage as a valid input you have to explicitly check for undefined, with an if -statement. But that was the one thing we tried to avoid. The solution, use default parameter values:

Now, this case is closed. But what about variables and object properties? Are these files now put to the cold cases? No! Take a step back and track down the murderer's path… I mean, take a step back and search for the true problem here. Whenever such a check is done, the mentality is: If it is undefined or null, take the default value, every other value is great.

ECMAScript 2020 introduced the Nullish-Coalescing operator to solve this problem. When you have a C# background, you know this beauty, the ?? sign. It does semantically the exact thing.

Summary of the Nullish-Coalescing operator: If the left side is neither null nor undefined, take the left side. If the left side is either null or undefined, take the right side.

Pretty hairstyle and nice voice (Elvis operator / Optional chaining operator)

A Big Hunk O’ Love — Elvis Presley

We got another star here, also known from C#. It is the Elvis operator (compare picture). Officially named “Optional Chaining operator”. Use this one when you want to chain the properties of objects. You use there the dot-operator to access a property or method of an object. But the dot-operator leads to a crash if the one you want to access isn’t defined.

Instead of crashing, the Elvis operator breaks out and cancel the access to return undefined. Before ECMAScript 2020, you had to use nested if-statements to check each part of the path deep down into the object’s properties and method depth. But like Elvis, we don’t live in those times anymore.

Today just take this operator that works like: Is the left side defined, take the property/method on the right side and access, if not — return undefined.

ATTENTIONBOX: Inside path tracking of an object with only “?” instead of “?:” it is the same behavior. Either get what's in the left side if it is not undefined or get a predefined value back. Although they look different it is the same operator. “?:” gets also called the ternary operator.

Conclusion

The ECMAScript provides us big updates and small updates. This article shows you what happened for the little ones and how to enhance your coding experience, by outsourcing the tedious tasks. Take the introduced improvements here to enlighten your coding, having more time to do the really cool tasks. JavaScript isn’t fully evolved. If you look into the TC39 Agenda you will see how much there is left in order to come closer to the ultimate goal, if there is one at least. A language is a living construct. [5]

What I think is interesting, that JavaScript becomes like C#. C# otherwise developed during the last years to a more functional language. And also Typescript, the superset of JavaScript, is like the best parts of both languages. Like a child of them both. Will this result in a super child and we will turn our backs against C# and JavaScript to only use TypeScript?

We will see. For now, look into the TC39 Agenda and stay tuned for the next article, when I sum up, what's about ECMAScript 2021![5]

Read On

Links & References

[1] Number.MAX_SAFE_INTEGER https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER

[2] Difference between “==” and “===” https://stackoverflow.com/questions/359494/which-equals-operator-vs-should-be-used-in-javascript-comparisons

[3] Operators & BigInt Doku: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt

[4] Smashing Magazine Essential Guide BigInt https://www.smashingmagazine.com/2019/07/essential-guide-javascript-newest-data-type-bigint/

[5] TC39 Agenda

https://github.com/tc39/agendas/blob/master/2020/11.md