By Carlos Caballero

Source: Dev

Translator: Front-end wisdom

The more you know, the more you don’t know

Like it and see. Make it a habit


GitHub: github.com/qq449245884… Has included more categories of previous articles, as well as a lot of my documentation and tutorial material. Welcome Star and Perfect, you can refer to the examination points for review in the interview, I hope we can have something together.

Everyone said there was no project on your resume, so I found one and gave it away【 Construction tutorial 】.

While ES10 doesn’t have as many new features as ES6, ES10 still has some useful features. This article introduces the new ES10 features through simple examples. In this way, we can understand quickly without having to read too much official explanation.

The new ES10 features are as follows:

  • Array methods:flatandflatMap
  • Object.fromEntries
  • String methods:trimStarttrimEnd
  • The Symbol ofdescriptionattribute
  • Try {} catch {} // Catch can be omitted
  • JSON ⊂ ECMAScript (make ECMAScript compatible with all JSON supported text)
  • Well-formed json.stringify ()
  • The stability of theArray.prototype.sort()
  • The revisedFunction.toString
  • BigInt is the seventh primitive type
  • Dynamic import
  • standardizedglobalThisobject

1. Array.flat() && Array.flatMap

The array.flat () method iterates through the Array recursively at a specified depth and returns a new Array with all the elements in the traversed subarray.

The array.flatmap () method first maps each element using a mapping function, and then compresses the result into a new Array. It is almost identical to a map and a flat with a depth value of 1, but flatmaps are usually slightly more efficient when combined into one method.

Example 1:

Array.flat()

Let multi = [1, 2, 3, 4 and 6, [7,8,9, final three [10]]]]. multi.flat(); / / [6, Array (4)]. Multi flat () flat (); / / [1,2,3,4,5,6,7,8,9, Array (3)] multi. Flat () flat (), flat (); / / multi,2,3,4,5,6,7,8,9,10,11,12 [1]. The flat (Infinity); / /,2,3,4,5,6,7,8,9,10,11,12 [1]Copy the code

Array.flatMap()

let array = [1, 2, 3, 4, 5];

array.map(x => [x, x * 2]);
Copy the code

Array now results:

[Array(2), Array(2), Array(2)]
0: (2)[1, 2]
1: (2)[2, 4]
2: (2)[3, 6]
Copy the code

Using flatMap:

array.flatMap(v => [v, v * 2]);
[1, 2, 2, 4, 3, 6, 4, 8, 5, 10]
Copy the code

Comprehensive examples:

2.Object.fromEntries()

The object.fromentries () method converts the list of key-value pairs to an Object.

Example 1:

let obj = { apple : 10, orange : 20, banana : 30 };
let entries = Object.entries(obj);
entries;
(3) [Array(2), Array(2), Array(2)]
 0: (2) ["apple", 10]
 1: (2) ["orange", 20]
 2: (2) ["banana", 30]
let fromEntries = Object.fromEntries(entries);
{ apple: 10, orange: 20, banana: 30 }
Copy the code

Case 2:

3.String.protype.matchAll

One early question was, how do YOU write the regular expression “match All”?

The best answer would suggest string. match with regular expressions and /g or RegExp. Exec with /g or RegExp. Test with /g.

Let’s take a look at how the old specification worked.

String.match with a String argument returns only the first match:

let string = 'Hello';
let matches = string.match('l');
console.log(matches[0]); // "l"
Copy the code

The result is a single “L” (note: matches are stored in matches[0], not matches)

The same is true for string.match with the regex argument:

Use the regular expression /l/ to find the “l” character in the string “hello” :

let string = "Hello";
let matches = string.match(/l/);
console.log(matches[0]); // "l"
Copy the code

Add /g mix

let string = "Hello"; let ret = string.match(/l/g); / / (2) (" l ", "l");Copy the code

So why use the new matchAll approach? Before we answer that question, let’s take a look at the capture group.

Regular expression capture group

Capturing groups in regex simply extracts a pattern from the () parentheses, and you can capture groups using /regex/.exec(string) and String.match.

Regular capture groups are created by wrapping the pattern in (pattern), but create the Groups attribute on the resulting object, which is: (? < name > pattern).

To create a new group name, simply append?

, in the result, the group match will become group.name and be appended to the match object. Here is an example:

String sample match:

Create mate.groups. Color and mate.groups. Bird:

const string = 'black*raven lime*parrot white*seagull'; const regex = /(? <color>.*?) A \ * (? <bird>[a-z0-9]+)/g; while (match = regex.exec(string)) { let value = match[0]; let index = match.index; let input = match.input; console.log(`${value} at ${index} with '${input}'`); console.log(match.groups.color); console.log(match.groups.bird); }Copy the code

The regex.exec method needs to be called multiple times to traverse the entire search result set. When.exec is called during each iteration, the next result is displayed (it does not return all matches immediately), so a while loop is used.

The output is as follows:

black*raven at 0 with 'black*raven lime*parrot white*seagull'
black
raven
lime*parrot at 11 with 'black*raven lime*parrot white*seagull'
lime
parrot
white*seagull at 23 with 'black*raven lime*parrot white*seagull'
white
seagull
Copy the code

But here’s the weird thing:

If you remove /g from this regular expression, you will always create an infinite loop on the first result. This was a great pain in the past. Imagine receiving a regular expression from a database, and you’re not sure if it has a /g at the end. You have to check first.

Good reason to use.matchall ()

  1. When used with capture groups, it canMore elegantThe capture group is just used(a)Extract a portion of the pattern’s regular expression.
  2. It returns an iterator instead of an array, and the iterator itself is useful.
  3. Iterators can use extension operators (…) Convert to an array.
  4. It avoids carrying/gFlag a regular expression when retrieving an unknown regular expression from a database or external source and associating it with staleRegExObject is very useful when used together.
  5. Regular expressions created using RegEx objects cannot use dots(.).Operator links.
  6. Advanced: RegEx object changes track the interior of the last matched location.lastindexProperty, which can wreak havoc in complex situations.

How does.matchall () work?

Let’s try to match all instances of the letters E and L in the word hello. Since iterators are returned, we can use for… The of loop iterates through it:

// Match all occurrences of the letters: "e" or "l" 
let iterator = "hello".matchAll(/[el]/);
for (const match of iterator)
    console.log(match);
Copy the code

This time you can skip /g, the.matchall method doesn’t need it, and the result is as follows:

[ 'e', index: 1, input: 'hello' ] // Iteration 1
[ 'l', index: 2, input: 'hello' ] // Iteration 2
[ 'l', index: 3, input: 'hello' ] // Iteration 3
Copy the code

Sample group capture using.matchall () :

const string = 'black*raven lime*parrot white*seagull'; const regex = /(? <color>.*?) A \ * (? <bird>[a-z0-9]+)/; for (const match of string.matchAll(regex)) { let value = match[0]; let index = match.index; let input = match.input; console.log(`${value} at ${index} with '${input}'`); console.log(match.groups.color); console.log(match.groups.bird); }Copy the code

Note that there is no /g flag because.matchall () already contains it, printed as follows:

black*raven at 0 with 'black*raven lime*parrot white*seagull'
black
raven
lime*parrot at 11 with 'black*raven lime*parrot white*seagull'
lime
parrot
white*seagull at 23 with 'black*raven lime*parrot white*seagull'
white
seagull
Copy the code

It is perhaps aesthetically very similar to the original regular expression, implementing a while loop. But as mentioned earlier, this is the better approach for many of the reasons mentioned above, and removing /g does not cause an infinite loop.

Comprehensive examples:

4. String. TrimStart () and String. TrimEnd ()

TrimStart () : Removes the leading space of the string.

TrimEnd () : Removes the space at the end of the string.

Example 1:

let greeting = "     Space around     ";
greeting.trimEnd();   // "     Space around";
greeting.trimStart(); // "Space around     ";
Copy the code

Case 2:

5.Symbol.Description

Description is a read-only property that returns a string of optional descriptions of the Symbol object.

Example 1:

let mySymbol = 'My Symbol';
let symObj = Symbol(mySymbol);
symObj; // Symbol(My Symbol)
symObj.description; // "My Symbol"
Copy the code

Case 2:

6. The catch parameter can be omitted

In the past, the catch statement in a try/catch statement required a variable. Try /catch statements help catch terminal level errors:

try {
    // Call a non-existing function undefined_Function
    undefined_Function("I'm trying");
}
catch(error) {
    // Display the error if statements inside try above fail
    console.log( error ); // undefined_Function is undefined
}
Copy the code

In some cases, the required error variable is not used:

try {
    JSON.parse(text); // <--- this will fail with "text not defined"
    return true; <--- exit without error even if there is one
}
catch (redundant_sometmes) <--- this makes error variable redundant
{
    return false;
}
Copy the code

In ES10, catching error variables is optional, and error variables can now be skipped:

Example 1:

try {
    JSON.parse(text);
    return true;
}
catch
{
    return false;
}
Copy the code

Case 2:

7. JSON ⊂ ECMAScript

What is a JSON superset? Remember ⊂ the symbol ⊂ can be interpreted as JSON ⊂ ECMAScript, in short, to make ECMAScript compatible with all JSON supported text. ECMAScript states in the standard Json.parse section that JSON is a subset of this, but because JSON content can normally contain U+2028 line delimiters and U+2029 paragraph delimiters, ECMAScript cannot.

The draft aims to address this problem. Before this, if you executed a string with json.parse () with the above special characters, you would only get a SyntaxError. This draft is also backward compatible, and the only effect on the user is to leave it as is, leaving SyntaxError in a runtime environment that does not currently support special character parsing.

8. Well-formed json.stringify ()

This update fixes the handling of characters U+D800 through U+DFFF, sometimes into JSON strings. This can be a problem because json.stringify may format these numbers into values that do not have utF-8 characters equivalent, but the JSON format requires UTF-8 encoding.

Parsing methods use well-formed JSON strings, such as:

'{" prop1 ": 1, "prop2" : 2}'; // A well-formed JSON format stringCopy the code

Note that to create a properly jSON-formatted string, it is absolutely necessary to enclose double quotes around the attribute name. The absence or any other type of quotation marks will not produce well-formed JSON.

'{ “prop1” : 1, "meth" : () => {}}'; // Not JSON format string
Copy the code

The JSON string format is different from the Object Literal format, which looks almost the same, but can enclose attribute names in quotes of any type, as well as include methods (the JSON format does not allow methods):

let object_literal = { property: 1, meth: () => {} };
Copy the code

Anyway, everything seems to be fine. The first example looks compatible. But they are also simple examples that work well most of the time!

U+2028 and U+2029 characters

The problem is that EcmaScript prior to ES10 doesn’t actually fully support JSON. The pre-ES10 era did not accept unescaped line delimiter U+2028 and paragraph delimiter U+2029 characters:

The same is true for all characters between U+D800 – U+DFFF

If these characters sneak into a JSON-formatted string (presumably from a database record), you can spend hours trying to figure out why the rest of the program produced parsing errors.

So, if you pass a string “console.log(‘ hello ‘)” like eval, it will execute JS statements (by trying to convert the string into actual code), similar to how json.parse will handle your JSON string.

The solution suggested in ES10 is to represent unpaired proxy code points as JSON escape sequences rather than returning them as individual UTF-16 code units.

9. Stable array.prototype.sort ()

Previous implementations of V8 used an unstable quicksort algorithm for arrays containing more than 10 items.

A stable sorting algorithm is one in which two objects with equal key values appear in the sorted output in the same order as in the unsorted input.

But that’s no longer the case, ES10 provides a stable array sort:

var fruit = [ { name: "Apple", count: 13, }, { name: "Pear", count: 12, }, { name: "Banana", count: 12, }, { name: "Strawberry", count: 11, }, { name: "Cherry", count: 11, }, { name: "Blackberry", count: 10, }, { name: "Pineapple", count: 10, } ]; // create sort function: let my_sort = (a, b) => a.ount-b.ount; // Perform stable ES10 sort: let sorted = fruit.sort(my_sort); console.log(sorted);Copy the code

Console output (items appear in reverse order):

Case 2:

10. The new Function. The toString ()

Function is an Object, and each Object has a. The toString () method, because it exists in the originally Object. The prototype, the toString (). All objects, including functions, are inherited from it through prototype-based class inheritance.

This means we already had the funcion.toString() method before.

But ES10 takes a further attempt to standardize the string representation of all objects and built-in functions. Here are the new cases:

Typical examples:

function () { console.log('Hello there.'); }.toString();
Copy the code

Output:

⇨ function () {console.log('Hello there.'); }Copy the code

Directly in the method name.toString()

Number.parseInt.toString(); ⇨ function parseInt() {[native code]}Copy the code

Binding context:

function () { }.bind(0).toString(); ⇨ function () {[native code]}Copy the code

Built-in callable function objects:

Symbol.toString(); ⇨ function Symbol() {[native code]}Copy the code

Dynamically generated functions:

function* () { }.toString(); ⇨ function* () {}Copy the code

prototype.toString

Function.prototype.toString.call({}); ⇨ Function. The prototype. ToString requires that 'this' be a Function"Copy the code

11.BigInt – An arbitrary precision integer

BigInt is the seventh primitive type.

BigInt is an integer of arbitrary precision. This means that variables can now represent the ²⁵³ number, not just 9007199254740992.

const b = 1n; // Append n to create BigIntCopy the code

In the past, integer values greater than 9007199254740992 were not supported. If exceeded, this value is locked to MAX_SAFE_INTEGER + 1:

const limit = Number.MAX_SAFE_INTEGER; ⇨ 9007199254740991 LIMIT + 1; ⇨ 9007199254740992 LIMIT + 2; ⇨ 9007199254740992 <-- MAX_SAFE_INTEGER + 1 exceeded const larger = 9007199254740991n; ⇨ 9007199254740991n const INTEGER = BigInt(9007199254740991); // Initialize with number ⇨ 9007199254740991n const same = BigInt("9007199254740991"); // Initialize with "string" ⇨ 9007199254740991nCopy the code

12. Dynamic import

Dynamic import returns a promise for the module namespace object that requests the module. Therefore, async/await can be used in conjunction.

Example 1:

element.addEventListener('click', async() => {
  const module = await import(`./api-scripts/button-click.js`);
  module.clickEvent();
})
Copy the code

Case 2:

13. Standardize globalThis objects

GlobalThis was not standardized prior to ES10, and in normal projects it was possible to accommodate different platforms in the following ways:

var getGlobal = function () { if (typeof self ! == 'undefined') { return self; } if (typeof window ! == 'undefined') { return window; } if (typeof global ! == 'undefined') { return global; } throw new Error('unable to locate global object'); };Copy the code

But even that doesn’t always work. As a result, ES10 added a globalThis object, which from now on is used to access the global scope on any platform:

But even that doesn't always work. As a result, ES10 added a globalThis object, which from now on is used to access the global scope on any platform:Copy the code

After school time all spend big arrange article of, quite bitter of, do not know have appreciation to buy a chicken leg of.

conclusion

JS is a dynamic language, which is very useful for Web development. The JS language has undergone a dynamic evolution since the advent of ES6 in 2015. In this article, we review the features that emerged in ES10(2019) and introduce some that will remain stable in ES11(2020) because they are in State 3 and are likely to be standardized in the next release.

While many of these features may not be necessary for the development of Web applications, some can rule out code that we’ve previously implemented with trickery or a lot of verbosity.


The bugs that may exist after code deployment cannot be known in real time. In order to solve these bugs, I spent a lot of time on log debugging. Incidentally, I recommend a good BUG monitoring tool for youFundebug.

Original text: dev. To/carlillo / 12…


communication

This article is updated every week, you can search wechat “big move the world” for the first time to read and urge more (one or two earlier than the blog hey), this article GitHub github.com/qq449245884… It has been included and sorted out a lot of my documents. Welcome Star and perfect. You can refer to the examination points for review in the interview.