The “dream” of lifelong learning for JavaScript developers has been realized thanks to TC39’s annual pace of adopting ECMAScript standards since 2015. It’s been more than three years since ES6 was released by word of mouth, and it’s been a few months since ECMAScript2018 was released in the middle of the year. How do you catch up with ECMAScript at the end of 2018?

This article takes a look at some of the new ECMAScript2018 standards features and some of the interesting proposals in their infancy.

For the convenience of readers, please note that “ECMAScript2018” mentioned in this article is equivalent to “ES9”. “Stage 1/2/3/4” and other concepts can be referred to
TC39 definition.


This article on compatibility evaluation to choose the “Chrome/Edge/Opera/Safari/Firefox” five kinds of major browsers and “Node” runtime and complete assessment can refer to
Can I use.

New ECMAScript features and standard proposals

1. The ES module

The first is the ES module. Because historically JavaScript did not provide a module system, in ancient times we used multiple script tags to manually isolate code. But thanks to the unity of the ES standard discussed by browsers and Node.js, we can now write ES module syntax directly in browsers. For example, if we create a new lib. MJS file and export a function in it, then in main. MJS I can import and use it directly.

// lib.mjs
export const repeat = (string) => `${string} ${string}`;

// main.mjs
import {repeat} from './lib.mjs';
repeat('#io18');
Copy the code

In the browser we can introduce the ES module with type=”module”. We can also introduce a JavaScript file for browsers that don’t support the ES module. Adding rel=” modulePreload “we can tell the browser to preload some common libraries and code.

// browser <script type="module" SRC ="/mypath_to_js_module. MJS "></script> <script nomodule SRC ="fallback.js"></script> // preload <link rel="modulepreload" href="lib.mjs" >Copy the code

The MJS suffix is used in all of the above versions, but it is not mandatory to reference ES modules in the browser, but MJS is required in the experimental new Node feature.

node --experimental-modules main.mjs
Copy the code

Compatibility is as follows


2. Number delimiter

Given a long list of numbers, how do you quickly identify them?

1000000000000
1019436871.42
Copy the code

If we could write it differently, it would make a lot of sense:

1 _000_000_000_000 _019_436_871. 42Copy the code

For non-decimal values, ES allows us to use underscores as well

// Hexadecimal 0b01001001_00101111_01001111 0x23_69_6F_31_38Copy the code

Unfortunately this is still a Stage 2 proposal, but fortunately we have Babel. The compatibility is as follows:


3. BigInt

What is the safe integer range in JavaScript? Console. log. Before this, if we tried to manipulate a value outside the safe integer range, the result would not be guaranteed to be correct. The same problem happened with Node, where there was an issue about Node occasionally assigning the same inode number to multiple files/folders.


We can now use BigInt for integer operations that are outside the safe integer range that Number can represent. There was a lot of Polyfill support, but now we have official support.

console.log(Number.MIN_SAFE_INTEGER); // 9007199254740991 console.log(Number.MAX_SAFE_INTEGER); BigInt(number.max_safe_INTEGER) + 2n; BigInt(number.max_safe_INTEGER) + 2n; BigInt(number.max_safe_integer) + 2n; // → 9007199254740993n Correct 1234567890123456789 * 123; // → 151851850485185200000 Error 1234567890123456789n * 123n; // → 151851850485185185047n Correct 42n === BigInt(42); typeof 123n; / / 'bigint bigint (1.5); / / - > RangeError BigInt (' 1.5 '); / / > SyntaxErrorCopy the code

The compatibility is as follows:


4. Async Iterator/Generator

We might be used to manipulating a data read like this:

const print = (readable) => {
    readable.setEncoding('utf8');
    let data = '';
    readable.on('data', (chunk) => {
        data += chunk;
    });
    readable.on('end', () => {
        console.log(data);
    })
}

const fs = require('fs');
print(fs.createReadStream('./file.txt'));
Copy the code

But the good news is that await supports for-each of, so we can write:

async function print(readable) {
    readable.setEncoding('utf8');
    let data = '';
    for await (const chunk of readable) {
        data += chunk;
    }

    console.log(data);
}

const fs = require('fs');
print(fs.createReadStream('./file.txt'));
Copy the code

compatibility


5. Regular matching and string operation

Now let’s look at the dotAll pattern. We’ve all used string templates, like what do we do to match Hello World?

const input = `
Hi, Fliggy. Hello 
world.
`;

/Hello.world/u.test(input); // false
Copy the code

We might think. Can represent any character, but not in this case, because a newline character does not match. So we can do this:

/Hello[\s\S]world/u.test(input); // All Spaces match all non-spaces /Hello[^]world/u.test(input); // All non-null matchesCopy the code

Now ES supports dotAll, so we can write:

/Hello.world/su.test(input); // true
Copy the code

Name Capture: Name Capture: Name Capture: Name Capture: Name Capture: Name Capture: Name Capture: Name Capture: Name Capture

const pattern = /(\d{4})-(\d{2})-(\d{2})/u;
const result = pattern.exec('2017-07-10');
// result[0] === '2017-07-10'
// result[1] === '2017'
// result[2] === '07'
// result[3] === '10'
Copy the code

Now we can write:

const pattern = /(? <year>\d{4})-(? <month>\d{2})-(? <day>\d{2})/u; const result = pattern.exec('2017-07-10'); // result.groups.year === '2017' // result.groups.month === '07' // result.groups.day === '10'Copy the code

For extremely complex regular expressions, the advantages of the new feature writing approach can be realized.

The third feature comes from Unicode character matching. Now ES provides two simple matching methods, \p{… } is used to match non-binary Unicode characters, while \P{… } is the opposite.

/ \ p {Number} / u.t est (' 1 '); // true/p{Alphabetic}/u.test(' Alphabetic '); / / true / \ P {Number} / u.t est (' 1 '); // false/P{Alphabetic}/u.test(' Alphabetic '); / / false / ^ \ p {Math} + $/ u.t est (' ∛ up ∉ '); / / true / ^ \ p {Script_Extensions = Hiragana} + $/ u.t est (' ひ ら が な '); // trueCopy the code

All of these methods are equally compatible and currently not supported by Edge or Firefox.


The fourth feature is full string matching. With the String matchall feature, we can matchall of the regular expressions in a while loop directly with.matchall:

const string = 'Magic hex numbers: DEADBEEF CAFE 8BADF00D'; const regex = /\b\p{ASCII_Hex_Digit}+\b/gu; let match; While (match = regex.exec(string)) {console.log(match); } // New method for (const match of string.matchall (regex)) {console.log(match); }Copy the code

The new feature is still in Stage 3, so the support is touching, but there are already many polyfills in the community that support this approach.


6. catch binding

Re’s are always hard to understand. Here’s a simpler new feature: try/catch. Now we can optionally decide whether or not a catch is added.

Try {} catch (e) {} // try {} catch {} // nowCopy the code

compatibility


7. trim

If you were given a string, what would you do if you were asked to remove the space at the beginning of hello or the space at the end?

const string = '      hello        ';
Copy the code

In the old days, you probably had to do it with the re, but now the trimStart and trimEnd methods do it.

string.trim(); // 'hello';
string.trimStart(); // 'hello        ';
string.trimEnd(); // '      hello';
Copy the code

compatibility


8. Promise.prototype.finally

Promise we all wrote, suppose we fetch a piece of data, we need to load the loading animation before the result comes back, and after the result comes back we need to remove the animation whether it is correct or wrong. In the old days, we needed to write the same logic in several places (see isLoading = false; Writing) :

let isLoading = true; fetch(myRequest).then(function(response) { var contentType = response.headers.get("content-type"); if(contentType && contentType.includes("application/json")) { return response.json(); } throw new TypeError("Oops, we haven't got JSON!" ); }) .then(function(json) { isLoading = false; }) .catch(function(error) { isLoading = false; console.log(error); });Copy the code

Now the addition of finally to the Promise prototype method gives us less redundant code.

let isLoading = true; fetch(myRequest).then(function(response) { var contentType = response.headers.get("content-type"); if(contentType && contentType.includes("application/json")) { return response.json(); } throw new TypeError("Oops, we haven't got JSON!" ); }) .then(function(json) { /* ... */ }) .catch(function(error) { console.log(error); }) .finally(function() { isLoading = false; });Copy the code

compatibility


9. Object deconstruction

We are all familiar with the concept of deconstruction, and perhaps we have been using it without any perception. However, ES2015 only provides the standard of array deconstruction, and the object deconstruction operation is still in stage 3 until the beginning of 2017.

Const person = {firstName: 'Sebastian', lastName: 'Markbage ', country: 'USA', state: 'CA',}; const { firstName, lastName, ... rest } = person; console.log(firstName); // Sebastian console.log(lastName); / / Markbage console. The log (rest); // { country: 'USA', state: 'CA' } // Spread const personCopy = { firstName, lastName, ... rest }; console.log(personCopy); // {firstName: 'Sebastian', lastName: 'Markbage ', country: 'USA', state: 'CA'}Copy the code

In many cases, Object deconstruction provides a more elegant alternative to object.assign (), such as merging two objects:

const defaultSettings = { logWarnings: false, logErrors: false };
const userSettings = { logErrors: true };

// 老方式
const settings1 = Object.assign({}, defaultSettings, userSettings);

// 新方式
const settings2 = { ...defaultSettings, ...userSettings };

// 结果
// { logWarnings: false, logErrors: true }
Copy the code

compatibility


10. Class

Finally, let’s talk about classes in JavaScript. First, the field definition. No longer limited to the (constructor) function, we can define the instanceProperty and staticProperty as follows:

class MyClass {
    instanceProperty = 0;
    static staticProperty = 0;
}
Copy the code

Secondly, the definition and use of private variables. For most of its history, JavaScript has lacked the concept of private variables that other programming languages use as a “regular army”, and developers have long implemented this functionality through closures. Now, the standard gives the language ES the possibility of having private variable definitions.

In terms of methods, if we need to define attributes in class that are accessible only in the class, we need to define private variables starting with #, as follows:

class MyClass { #foo; Constructor (foo) {this.#foo = foo; } incFoo() { this.#foo++; }}Copy the code

To date, this feature has not been implemented in major browsers or Node.


The definition of private variables has been ridiculed by many developers as “ugly”, but “unfortunately” the proposal is already in stage 3. See the proposal for details
Github.com/tc39/propos…

Afterword.

There is a question on Zhihu asking “Why are so many companies still using JDK6?” The author is puzzled by the fact that many companies still use older Versions of Java even though JDK11 has been released. On the other hand, the JavaScript(ECMAScript) ecosystem, while ECMAScript2018 was still in its final form, many developers were able to use the new syntax to produce code that was still in Stage 3. Java and JavaScript are not only similar in relation to Leifeng Tower, but also in terms of language standards, the attitude of developers on the two sides is completely opposite.

ECMAScript’s journey is a sea of stars, following in TA’s footsteps.

reference

  • Build the future of the web with modern JavaScript
  • Github.com/tc39/propos…
  • BigInt: an arbitrary precision integer in JavaScript
  • 2 ality.com/2016/10/asy…
  • Github.com/tc39/propos…
  • Developers.google.com/web/updates…

Get on the ECMAScript bandwagon: Program in modern JavaScript

Search “Anxiao” on wechat or scan this QR code

Zhihu Column – Junior front-end Engineer

Life will inevitably make mistakes, please give more advice!