ECMAScript2019 (ES10) is fast approaching. Features are moving into Stage 4, which is the final stage, and so we have some cool things to look forward to. Here’s what we know about so far.
Features in ECMAScript2019 (ES10)
Array.prototype.flat
A method that creates a new array with all sub-array elements concatenated into it recursively up to the specified depth.
const array = [1, 2, [3, 4]];
array.flat(); // [1, 2, 3, 4];
When you want to flatten your nested array, you’ll find this to be very helpful. If the depth of your array is deeper than one depth, calling flat
once can’t entirely flatten your array. flat
takes a parameter for depth, which refers to how many depths you want it to go into to flatten the array.
// Extreme!!! example
const crazyArray = [1, 2, [3, 4], [[5], [6, [7,8]]]];
crazyArray.flat(Infinity); // [1, 2, 3, 4, 5, 6, 7, 8];
// The parameter must be a typeOf Number
The deeper you want to search the array, the more computing time will be required to flatten it. Note that IEs and Edge do not support this feature.
Array.prototype.flatMap
A method first maps each element using a mapping function, then flattens the result into a new array.
const arr = ["it's Sunny in", "", "California"];
arr.flatMap(x => x.split(" "));
// ["it's","Sunny","in", "", "California"]
The difference between flat
and flatMap
is that you can put a custom function in flatMap
to manipulate each value. Additionally, unlike flat
, flatMap
flattens one depth array, only. The return value should be an array type. This would be very useful when you should do something before flattening the array.
Click here if you want to know more features added to ES10.
Optional Chaining
This proposal goes with Nullish Coalescing for JavaScript, especially in TypeScript. TypeScript has announced that they will include Nullish Coalescing for JavaScript and this proposal in their next released version, 3.7.0.
const city = country && country.city;
// undefined if city doesn't exist
Look at the example code. To get city
, which is in country
object, we should check if country
exists and if city
exists in country
.
With Optional Chaining, this code can be refactored like this:
const city = country?.city; // undefined if city doesn't exist
This feature seems very handy and useful for this situation.
import { fetch } from '../yourFetch.js';
(async () => {
const res = await fetch();
// res && res.data && res.data.cities || undefined
const cities = res?.data?.cities;
})();
Nullish Coalescing for JavaScript
This would be one of the most useful features amongst proposals in stage 3. We often wrote this kind of code.
const obj = {
name: 'James'
};
const name = obj.name || 'Jane'; // James
If obj.name
is falsy, then return ‘Jane’, so undefined
won’t be returned. But the problem is, an empty string(‘’
) is also considered falsy in this case. Then we should rewrite it again like this below.
const name = (obj.name && obj.name !== '') ? obj.name : 'Jane';
It is a pain in the neck to write the code like that every time. This proposal allows you to check null
and undefined
only.
const response = {
settings: {
nullValue: null,
height: 400,
animationDuration: 0,
headerText: '',
showSplashScreen: false
}
};
const undefinedValue = response.settings.undefinedValue ?? 'some other default'; // result: 'some other default'
const nullValue = response.settings.nullValue ?? 'some other default'; // result: 'some other default'
const headerText = response.settings.headerText ?? 'Hello, world!'; // result: ''
const animationDuration = response.settings.animationDuration ?? 300; // result: 0
const showSplashScreen = response.settings.showSplashScreen ?? true; // result: false
Features In Stage 3
In stage 3, there are a few features that might be interesting to have.
Numeric Separators
When you assigned a big number to a variable, weren’t you confused on how big that number is or if you wrote it right? This proposal allows you to put an underscore between numbers so you can count it easier.
1_000_000_000 // Ah, so a billion
101_475_938.38 // And this is hundreds of millions
let fee = 123_00; // $123 (12300 cents, apparently)
let fee = 12_300; // $12,300 (woah, that fee!)
let amount = 12345_00; // 12,345 (1234500 cents, apparently)
let amount = 123_4500; // 123.45 (4-fixed financial)
let amount = 1_234_500; // 1,234,500
let budget = 1_000_000_000_000;
// What is the value of `budget`? It's 1 trillion!
//
// Let's confirm:
console.log(budget === 10 ** 12); // true
This feature could help you out when counting the size of a number.
Top-level await
Top-level await
enables modules to act as big async functions: With top-level await
, ECMAScript Modules (ESM) can await
resources, causing other modules who import
them to wait before they start evaluating their body.
The motivation of this feature was that when you import
a module which has async
function, the output of the async
function is undefined
.
// awaiting.mjs
import { process } from "./some-module.mjs";
const dynamic = import(computedModuleSpecifier);
const data = fetch(url);
export const output = process((await dynamic).default, await data);
There are two files. output
could be undefined
if it’s called before the Promises tasks are done.
// usage.mjs
import { output } from "./awaiting.mjs";
export function outputPlusValue(value) { return output + value }
console.log(outputPlusValue(100));
setTimeout(() => console.log(outputPlusValue(100), 1000);
usage.mjs
will not execute any of the statements in it until the await
s in awaiting.mjs
have had their Promises resolved.
Promise.any
Promise.any
accepts an iterable of promises and returns a promise that is fulfilled by the first given promise to be fulfilled, or rejected with an array of rejection reasons if all of the given promises are rejected.
With async
–await
,
try {
const first = await Promise.any(promises);
// Any of the promises was fulfilled.
} catch (error) {
// All of the promises were rejected.
}
With Promise pattern,
Promise.any(promises).then(
(first) => {
// Any of the promises was fulfilled.
},
(error) => {
// All of the promises were rejected.
}
);
Since there were Promise all
, allSettled
, and race
, there wasn’t any
. So this feature is simple but powerful for a needed situation.
However, this proposal wasn’t tested yet, so this proposal might have a longer time to be accepted in a future version of ECMAScript.
Conclusion
There are many interesting proposals in stage 3. They may not appear until ES11 or ES12. Obviously I won’t use all of them, and you probably won’t either. Some of them will be really helpful to have in our toolbelts, regardless of who we are.
Comments are closed.