Small knowledge, big challenge! This article is participating in the “Essentials for Programmers” creative activity. This article has participated in the “Digitalstar Project” to win a creative gift package and challenge the creative incentive money.
Following a quick look at ES feature 2 (ES9), today we will focus on the new ES feature ES10. We have already talked about the origin of ES, version corresponding rules and other contents, so I will not repeat them here, let’s directly start
A quick look at the ES features is part of my current series
- Quick introduction to one of ES features (ES7-ES8)
- Quick Introduction to ES Feature 2 (ES9)
- Quick Introduction to ES Feature # 3 (ES10)
ES2019 / ES10
Optional catch Binding Optional exception capture
Before ES10, when we tried a catch, we had to specify a thrown error on a catch. Now there is no need.
Here’s a quick example
/ / ES10 before
try {
throw `error`;
} catch (e) { // The caught exception must be declared
console.log(e);
}
/ / now,
try {
throw `error`;
} catch { // The errors caught here are now optional and can be left unwritten
}
Copy the code
JSON superset
Prior to ES10, ECMAScript did not support all JSON formats. Normal JSON characters can contain unescaped U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR characters, but ECMAScript does not support this. It is now happily supported from ES10 onwards. 🤣
const code = '"\u2028\u2029"';
// It used to explode with 'SyntaxError', now it doesn't
JSON.parse(code);
eval(code);
Copy the code
Symbol.prototype.description
Prior to ES10, we knew that the description of Symbol was passed in through a construct and could not be obtained directly. If we want to get it, we can only do the toString conversion
interface SymbolConstructor {
/**
* Returns a new unique Symbol value.
* @param description Description of the new Symbol object.
*/(description? :string | number): symbol;
}
Copy the code
const hi = Symbol("hi");
console.log(hi.toString());
// Symbol(hi)
console.log(hi.toString() === "Symbol(hi)");
// true
Copy the code
Now we can get the description directly
interface Symbol {
/** * Expose the [[Description]] internal slot of a symbol directly. */
readonly description: string | undefined;
}
Copy the code
const hi = Symbol("hi");
console.log(hi.description);
// hi
console.log(hi.description === "hi");
// true
Copy the code
Students can read the details here: Symbol Description accessor
Function.prototype.toString revision
Let’s go straight to the example:
function hi() {
// hello world
console.log(`hello world`);
}
console.log(hi.toString());
// function hi() {
// // hello world
// console.log(`hello world`);
// }
console.log(hi.toString.toString());
// function toString() { [native code] }
Copy the code
As we can see from the above example, the method’s toString() will print the real source code for the method, returning whatever it is written. Here also do not have what good say, want to know more students can view the details here:. The Function prototype. ToString revision
Object.fromEntries
In ES8, we added the Object.entries method to turn objects into an entry array. In ES10, a method to generate objects from an Entry array has been added.
interface ObjectConstructor {
/**
* Returns an object created by key-value entries for properties and methods
* @param entries An iterable object that contains key-value entries for properties and methods.
*/
fromEntries<T = any>(entries: Iterable<readonly [PropertyKey, T]>): { [k: string]: T };
/**
* Returns an object created by key-value entries for properties and methods
* @param entries An iterable object that contains key-value entries for properties and methods.
*/
fromEntries(entries: Iterable<readonly any[] >) :any;
}
Copy the code
FromEntries takes an iterable Object and then generates a new Object. Let me give you an example
const obj = { a: 1.b: 2.c: 3 };
const entries = Object.entries(obj);
// [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ]
const newObj = Object.fromEntries(entries);
// { a: 1, b: 2, c: 3 }
Copy the code
We can also generate it from a simple Map of strings as keys
const map = new Map().set(`a`.1).set(`b`.2).set(`c`.3);
const obj = Object.fromEntries(map);
console.log(obj);
// { a: 1, b: 2, c: 3 }
Copy the code
If it is not a string key, it will be automatically converted to a string
const map2 = new Map().set(1.1).set([1.2.3].2).set(Symbol(`hi`), 3);
const obj2 = Object.fromEntries(map2);
console.log(obj2);
// {'1': 1, '1,2,3': 2, [Symbol(hi)]: 3}
Copy the code
Iterables like Maps can also be transformed, such as URLSearchParams
const obj4 = Object.fromEntries(new URLSearchParams(`x=1&y=2`));
console.log(obj4);
// { x: '1', y: '2' }
Copy the code
We can also simply simulate an iterable ourselves
const mapLike = {
kv: {},
get(key) {
return this.kv[key];
},
set(key, value) {
this.kv[key] = value;
return this; },Symbol.iterator]() {
let index = 0;
const entries = Object.entries(this.kv);
return {
next() {
const entry = entries[index++];
return {
value: entry,
done:! entry, }; }}; }}; mapLike.set(`a`.1).set(`b`.2).set(`c`.3);
const obj5 = Object.fromEntries(mapLike);
console.log(obj5);
// { a: 1, b: 2, c: 3 }
Copy the code
We can also reduce the dimension of the object array to a simple key-value object
const arr = [
{ name: ` zhang SAN `.age: 26 },
{ name: 'Lin Dajun'.age: 18},];const obj3 = Object.fromEntries(arr.map(({ name, age }) = > [name, age]));
console.log(obj3);
// {' zhang SAN ': 26, 'Lin Dajun ': 18}
Copy the code
Object.fromEntries and Object.entries are a pair, and switching between them can be flashy.
FromEntries does the same for object.fromentries. Let’s move on to new features
Well-formed JSON.stringify
We know that when we return a JSON data from the back end we need to encode the JSON data in UTF-8 format. However, some unpaired UTF-16 code units (0xD800 — 0xDFFF) cannot be encoded into UTF-8 when we serialize using json.stringify. We can see that the UTF-16 agent pair is composed of one high agent (U+D800 — U+DBFF 1,024 code points) and one low agent (U+DC00 — U+DFFF 1,024 code points). As we can see from the bottom of our head, only half of UTF-16s can’t properly encode the right character. So in ES10 we modified json.stringify to handle these bad characters in a reasonable way: instead of encoding them, we escaped them.
// Correct pairs of UTF-16 encoding are non-BMP characters that can be printed correctly
JSON.stringify('𝌆')
/ / '" 𝌆 "'
JSON.stringify('\uD834\uDF06')
/ / '" 𝌆 "'
// Error unpaired UTF-16 proxy code units are converted to escape characters
JSON.stringify('\uDF06\uD834')
// '"\udf06\ud834"'
// Individual UTF-16 agent code units are also converted to escape characters
JSON.stringify('\uDEAD')
// '"\udead"'
Copy the code
The following example shows how json.stringify handles this part of the character as an escape character
console.log(JSON.stringify(`\u{D800}`) = = =`"\u{D800}"`);
// false
console.log(JSON.stringify(`\u{D800}`) = = =`"\ud800"`);
// true
Copy the code
String.prototype.{trimStart,trimEnd}
This feeling is nothing to write home about, mainly removing whitespace characters (Spaces, newlines, etc.) at both ends of the string.
interface String {
/** Removes the trailing white space and line terminator characters from a string. */
trimEnd(): string;
/** Removes the leading white space and line terminator characters from a string. */
trimStart(): string;
}
Copy the code
The trimLeft and trimRight methods are implemented in ES5. However, the new padStart and padEnd names on ES8 are not compatible with the new RTL friendly names for the trimLeft and trimRight. TrimStart and trimEnd. To ensure compatibility, Most engine will String. Prototype. TrimLeft. The name value trimLeft into trimStart, String. The prototype. TrimRight. The value of the name trimRight trimEnd.
Let’s give an example
const str = ` hi, star \n`;
console.log(str.length);
/ / 11
console.log(str.trimStart().length);
// 10 removes the left space
console.log(str.trimEnd().length);
// 9 removes a space and a newline character on the right
console.log(String.prototype.trimLeft.name === `trimStart`);
// true
console.log(String.prototype.trimRight.name === `trimEnd`);
// true
Copy the code
Array.prototype.{flat,flatMap}
ES10 adds two new operators to arrays: flat and flatMap. I’ll explain their functions and usage separately
flatFlattening an array
Flat is exactly what it is called. It flattens a nested array. By passing a depth argument, you can flatten an array that is nested at a given depth and return it as a new array. If you do not pass depth, which defaults to depth of 1, unpack a layer of nested arrays. If you pass Infinity, it will flatten all levels of the nested array, and by all, I mean any level, any number of levels, it will become a one-dimensional array, which is the most common way we use it.
interface Array<T> {
flat<A, D extends number = 1> (this: A, depth? : D ): FlatArray<A, D>[] }Copy the code
Here’s an example
const arr = [1[2[3[4[5.6]]]], [7[8[9[10]]]]];
console.log(arr.flat());// Unwrap a layer by default
/ / [1, 2, 3, [4, [5, 6]]], 7, [8, [9, [10]]]]
console.log(arr.flat(2));
/ / [1, 2, 3, 4, [5, 6]], 7, 8, [9, [10]]]
console.log(arr.flat(3));
// [1, 2, 3, 4, [5, 6], 7, 8, 9, [10]]
console.log(arr.flat(Infinity));
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Copy the code
The flat method also has the property of merging empty items as it expands. Empty items here only refer to items that have no value, not null or undefined
const arr2 = [1,,2.3[4.5]], null.undefined];
console.log(arr2.flat());
// [1, 2, 3, [4, 5], null, undefined] // Only empty items at the specified level will be merged
console.log(arr2.flat(Infinity));
// [ 1, 2, 3, 4, 5, null, undefined ]
Copy the code
Speaking of which, ONE of the fancier solutions I’ve seen is to expand all nested arrays. However, it is a Generator method
const arr = [1[2[3[4[5.6]]]], [7[8[9[10]]]]];
function* flat(arr) {
for (const it of arr) {
if (Array.isArray(it)) {
yield* flat(it);
} else {
yieldit; }}}// Using it directly returns a suspended Generator
console.log(flat(arr));
// flat{<suspended>}
// Here we use the expansion to consume, so we get the fully expanded array
const flatArr = [...flat(arr)];
console.log(flatArr);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Copy the code
flatMap
The flatMap method is a composite that converts a high-latitude value to a low-latitude value. It’s a combination of map and flat at a depth of 1.
interface Array<T> {
flatMap<U, This = undefined>(
callback: (this: This, value: T, index: number, array: T[]) = >U | ReadonlyArray<U>, thisArg? : This ): U[] }Copy the code
Let’s look at an example
const words = [`hello`.`world`];
const r1 = words.map((item) = > item.split(` `)).flat();
console.log(r1);
// ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']
const r2 = words.flatMap((item) = > item.split(` `));
console.log(r2);
// ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']
Copy the code
Does it look like it’s all the same? However, the performance of the second method is better because the first method runs twice with multiple loops in between. If we need to map and then flat layer later, we can use flatMap first. After all, flatMap has better performance.
The use of flatMap is not limited to the above scenario, as long as the above method definition, as long as it returns an array. Then we can add, delete, and modify the results
const words = [`hello`.`world`];
const r3 = words.flatMap((item, index) = >
(index === 0 ? item.split(` `).concat(`, `) : item.split(` `)));
console.log(r3);// Put a comma between words
// ['h', 'e', 'l', 'l', 'o', ',', 'w', 'o', 'r', 'l', 'd']
const nums = [1.2.3];
const r4 = nums.flatMap((item) = > [item, item ** item]);
console.log(r4);
// [1, 1, 2, 4, 3, 27]
Copy the code
conclusion
How time flies! It’s time to say good night again. Among the new ES10 features, I only felt that JSON superset and well-formed Json. stringify might need a little more reading, as they touch on the basics of ES. The rest are very common things, in other languages maybe years ago. These extensions only add to the experience, and it doesn’t matter if they’re there or not. But there are always fragrant, white piao the most cool, you can reduce a lot of template code. So, be sure to order more, okay?
If the article is helpful to you, welcome to like, comment, pay attention to, collect, share, your support is my code word power, thank you!! 🌈
If the content of the article is wrong, welcome to correct, exchange, thank 😘
Finally, you can click here to join the QQ group FlutterCandies🍭 and communicate with various gurus
The resources
- Introduction to EMACScript and the latest specification
- The completed ES proposal
- Quick introduction to one of ES features (ES7-ES8)
- Quick Introduction to ES Feature 2 (ES9)
- Symbol description accessor
- Function.prototype.toString revision