ES2019
Array.prototype.flat()
const letters = ['a', 'b', ['c', 'd', ['e', 'f']]];
// default depth of 1
letters.flat();
// ['a', 'b', 'c', 'd', ['e', 'f']]
// depth of 2
letters.flat(2);
// ['a', 'b', 'c', 'd', 'e', 'f']
// which is the same as executing flat with depth of 1 twice
letters.flat().flat();
// ['a', 'b', 'c', 'd', 'e', 'f']
// Flattens recursively until the array contains no nested arrays
letters.flat(Infinity)
// ['a', 'b', 'c', 'd', 'e', 'f']
Array.prototype.flatMap()
let greeting = ["Greetings from", " ", "Vietnam"];
// let's first try using a normal `map()` function
greeting.map(x => x.split(" "));
// ["Greetings", "from"]
// ["", ""]
// ["Vietnam"]
greeting.flatMap(x => x.split(" "))
// ["Greetings", "from", "", "", "Vietnam"]
Object.fromEntries()
const keyValueArray = [
['key1', 'value1'],
['key2', 'value2']
]
const obj = Object.fromEntries(keyValueArray)
// {key1: "value1", key2: "value2"}
Function.prototype.toString()
function sum(a, b) {
return a + b;
}
console.log(sum.toString());
// function sum(a, b) {
// return a + b;
// }
String.prototype.trimStart()
/ .trimEnd()
let str = " this string has a lot of whitespace ";
str.length;
// 42
str = str.trimStart();
// "this string has a lot of whitespace "
str.length;
// 38
str = str.trimEnd();
// "this string has a lot of whitespace"
str.length;
// 35
Symbol.prototype.description
const me = Symbol("Alberto");
me.description;
// "Alberto"
me.toString()
// "Symbol(Alberto)"
ES2018
对象的 Rest / Spread 属性
let obj = {
a: 1,
b: 3,
c: 5,
d: 8,
};
let { a, b, ...z } = obj;
console.log(a); // 1
console.log(b); // 3
console.log(z); // { c: 5, d: 8 }
let clone = { ...obj };
console.log(clone); // { a: 1, b: 3, c: 5, d: 8 }
Lifting tagged template literals restrictions
const raw = String.raw`1\\2\\${1+2}`;
console.log(raw); //1\\2\\3
console.log(raw.length); //7
const x = `1\\2\\${1+2}`;
console.log(x); //1\2\3
console.log(x.length); //5
Asynchronous iteration
for await (const line of readLines(filePath)) {
console.log(line);
}
Promise.prototype.finally()
fetch('your-url')
.then(result => {
// ...
})
.catch(error => {
// ...
})
.finally(() => {
// ...
});
RegExp features
// flag for regular expressions
/foo.bar/.test('foo\nbar'); // false
/foo[^]bar/.test('foo\nbar'); // true
// RegExp named capture groups
let re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
let result = re.exec('2015-01-02');
// result[0]; // '2015-01-02'
// result[1]; // '2015'
// result[2]; // '01'
// result[3]; // '02'
// result.groups.year = '2015';
// result.groups.month = '01';
// result.groups.day = '02';
// RegExp lookbehind assertions
// make sure that a pattern is or isn't preceded by another
// Proposal Unicode Property Escapes
const regexGreekSymbol = /\p{Script=Greek}/u;
regexGreekSymbol.test('n'); // true
ES2017
padStart() & padEnd()
'hi'.padStart(10); // " hi"
'hi'.padEnd(10); // "hi "
// 不限于添加空格
'hello'.padEnd(11, ' world'); // "hello world"
Object.entries() & Object.values()
const core = {
amd: 'yes',
intel: 'no',
};
Object.entries(core); // [ [ 'amd', 'yes' ], [ 'intel', 'no' ] ]
Object.values(core); // [ 'yes', 'no' ]
Async & Await
function walk(amout) {
return new Promise((resolve, reject) => {
if (amout < 500) {
reject('the value is too small');
}
setTimeout(() => resolve(`walked for ${amout}ms`), amout);
});
}
async function go() {
const res = await walk(500);
console.log(res);
const res2 = await walk(900);
console.log(res2);
const res3 = await walk(600);
console.log(res3);
const res4 = await walk(700);
console.log(res4);
const res5 = await walk(400);
console.log(res5);
console.log('finished');
}
go();
// walked for 500ms
// walked for 900ms
// walked for 600ms
// walked for 700ms
// uncaught exception: the value is too small
ES2016
Array.prototype.includes()
let array = [1, 3, 5, 7, 9, 11];
// 检查元素是否出现在 Array 中
array.includes(3); // true
array.includes(2); // false
// 添加索引作为第二个参数
array.includes(3, 1); // true
array.includes(5, 4); // false
Exponentiation Operator(求冥运算)
// before
Math.pow(2, 3); // 8
// now
2**3 // 8