Expected New JavaScript Features That You Should Know About

Since the release of the ECMAScript 2015 standard (also called ES6), JavaScript has seriously changed and improved. This is very good news for all JS developers. Moreover, now a new version of ECMAScript is released every year. Perhaps you did not pay much attention to what appeared in the latest version of the standard, which was released in June 2019. The author of the article, the translation of which we are publishing today, wants to tell in a nutshell about the innovations of JavaScript, and about what can be expected in the next version of the ECMAScript standard.







Opportunities whose proposals are in the third stage of approval (Stage 3) will be mentioned here. This means that they are likely to appear in the next version of the ECMAScript standard, but this cannot be confirmed with absolute certainty. Here is the repository where you can find information about proposals that are at different stages of approval.



Features ECMAScript 2019 (ES10)



The ES10 standard has many new features. Here we will consider only some of them. Namely, a couple of new array methods.



▍ Array.prototype.flat Method



This method allows you to make arrays, which include other arrays, more "flat", "compressing" them to a given depth level.



const array = [1, 2, [3, 4]]; array.flat(); // [1, 2, 3, 4];
      
      





This is a very useful feature, especially in cases where you need to work with nested arrays. If the nesting depth of arrays in the data structure exceeds 1, then a single call to the flat



method cannot make the array completely “flat”. This method accepts an optional parameter depth



, which allows you to specify how many nesting levels the dimension of the processed array should be reduced.



 //   const crazyArray = [1, 2, [3, 4], [[5], [6, [7,8]]]]; crazyArray.flat(Infinity); // [1, 2, 3, 4, 5, 6, 7, 8]; // ,  flat,    
      
      





The deeper the array, the more computing resources will be needed to process it. Please note that IE and Edge do not support this feature.



▍ Method Array.prototype.flatMap



This method first processes the elements of the array using the function passed to it, and then converts the array into a flat structure.



 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 pass your own function to the flatMap



method, which converts the elements of the original array. In addition to this, flatMap



, unlike flat



, “raises” the elements of arrays only 1 level. This method returns a new array. It can be useful in those cases when, before you make a certain array “flat”, you need to somehow process its elements.



New JS Features at Stage 3 Approval



At the third stage of coordination, there are many interesting new proposals for expanding and improving the language. Let's consider some of them.



▍ Number digit separators



Did it happen to you: write a long number into a variable and doubt its correct spelling? The sentence in question allows you to separate the digits of numbers with underscores. This makes it easy to work with numbers.



 1_000_000_000      // ,   101_475_938.38     //     -     let fee = 123_00;    // $123 (, , 12300 ) let fee = 12_300;    // $12,300 (  !) let amount = 12345_00; // 12,345 (,  , 1234500 ) let amount = 123_45.00; // 12345 (, -  ) let amount = 1_234_500; // 1,234,500 let budget = 1_000_000_000_000; //   `budget`?  - 1 ! // // : console.log(budget === 10 ** 12); // true
      
      





Each developer, after accepting this feature, will decide for himself whether or not to use discharge separators. But one thing is for sure: this feature can reduce the inconvenience associated with calculating the digits of large numbers.



▍Using await at the top level of code



Using the await



keyword at the top level of the code allows modules to act as large asynchronous functions. Due to this feature, ECMAScript modules can expect some resources to appear. This leads to the fact that other modules importing them will wait until the body of the imported modules is ready for work.



The reason for this feature is that when a module is imported that has a function declared with the async



, the output of this function will be undefined



.



The following example shows two files. It may get undefined



in output



if the function is called before the tasks represented by the promises are completed.



 // 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); // usage.mjs import { output } from "./awaiting.mjs"; export function outputPlusValue(value) { return output + value } console.log(outputPlusValue(100)); setTimeout(() => console.log(outputPlusValue(100), 1000);
      
      





Everything will stop in the awaiting.js



until awaiting.js



are resolved in awaiting.js.



▍Operator ?? and checking values ​​only on null and undefined



Perhaps, among all the Stage 3 offers, this is the most useful. We often have to write something like this:



 const obj = {  name: 'James' }; const name = obj.name || 'Jane'; // James
      
      





If obj.name



is represented by some false value, then the string Jane



gets into name



. As a result, the name



will not appear to be something like undefined



. But the problem is that an empty string in this case will be perceived as a false value. If this is taken into account, this code should be rewritten as follows:



 const name = (obj.name && obj.name !== '') || 'Jane';
      
      





It’s inconvenient to write like that all the time. Operator ??



(two question marks) allows checking values ​​only on null



and undefined



:



 const response = {  settings: {    nullValue: null,    height: 400,    animationDuration: 0,    headerText: '',    showSplashScreen: false  } }; const undefinedValue = response.settings.undefinedValue ?? 'some other default'; // : 'some other default' const nullValue = response.settings.nullValue ?? 'some other default'; // : 'some other default' const headerText = response.settings.headerText ?? 'Hello, world!'; // : '' const animationDuration = response.settings.animationDuration ?? 300; // : 0 const showSplashScreen = response.settings.showSplashScreen ?? true; // : false
      
      





▍Operator?. and optional chains



This suggestion is close to the one just reviewed, combining null



and undefined



checks. It is known that users of TypeScript are interested in this feature.

Consider an example:



 const city = country && country.city; // undefined  city  
      
      





In order to get to the city



property of a country



object, you need to check the existence of the country



object and the existence of the city



property in it.



By using the operator ?.



(question mark and period) this code can be converted like this:



 const city = country?.city; // undefined  city  
      
      





This feature seems useful in such situations:



 import { fetch } from '../yourFetch.js'; (async () => {  const res = await fetch();  // res && res.data && res.data.cities || undefined  const cities = res?.data?.cities; })();
      
      





▍ Method Promise.any



The Promise.any



method accepts an Promise.any



object containing promise objects, and returns a promise that is successfully resolved when at least one of the promise objects passed to it is successfully resolved. If all the promise objects turn out to be rejected, it returns an array containing information about the reasons for their rejection.



This is how using Promise.any



with the async / await construct looks like:



 try {  const first = await Promise.any(promises);  //      . } catch (error) {  //    . }
      
      





Here is the same thing implemented using promises:



 Promise.any(promises).then(  (first) => {    //      .  },  (error) => {    //    .  } );
      
      





JavaScript already has Promise.all



, .allSettled



, .race



, but a similar method. any



, was not. As a result, we have a new opportunity that complements the existing ones and may prove useful in certain situations. Despite the fact that this proposal is already at the third stage of approval, it may not be included in the next edition of the ECMAScript standard as it needs additional testing.



Summary



There are many interesting suggestions for developing JavaScript that are in the third stage of approval. It will be interesting to see them in the ES11 and ES12 standards. Of course, it is unlikely that anyone will use them all, but some of them will definitely find wide application and will contribute to the growth of the quality of the JS code.



Dear readers! Are you already using any JavaScript features that are almost ready to be included in the next version of the standard?








All Articles