evantianx / Bloooooooog

Place to record what I thought and learned
0 stars 0 forks source link

ES7 & ES8 & ES9 #86

Open evantianx opened 6 years ago

evantianx commented 6 years ago

ECMAScript 2016

Array.prototype.includes

取代旧的查找方法 Array.prototype.indexOf

const arr = [1, 2, 3, 4, NaN]

// ~x  => -(x + 1)
if (~arr.indexOf(3)) {
  console.log(true)
}

if (arr.includes(3)) {
  console.log(true)
}

// Attention!
arr.includes(NaN) // true
arr.indexOf(NaN) // -1

Exponentiation infix operator

// equal to: Math.pow(7, 2)
7**2 //49
evantianx commented 6 years ago

ECMAScript 2017

Object.values()

类似于 Object.keys(),只不过返回的是对象自有属性的值组成的数组 :

const cars = { BMW: 3, Tesla: 2, Toyota: 1 }

// ES2015
const vals = Object.keys(cars).map(key => cars[key])  // [3, 2, 1]

// ES2017
const values = Object.values(cars)  // [3, 2, 1]

Object.entries()

返回值为带有 key 和 value 的数组格式,如 Object.entries({ a: 1, b: 2 }) 返回值为 [ [ 'a', 1 ], [ 'b', 2 ] ]

主要用于对象循环遍历:

const cars =  { BMW: 3, Tesla: 2, Toyota: 1 }

// ES5.1
Object.keys(cars).forEach(function(key) {
  console.log(`key: ${key} value: ${cars[key]}`)
})

// ES2017
for (let [key, value] of Object.entries(cars)) {
  console.log(`key: ${key} value: ${cars[key]}`)
}

以及 Object => Map :

const cars =  { BMW: 3, Tesla: 2, Toyota: 1 }

// ES2015
const map1 = new Map()
Object.keys(cars).forEach(key => {
  map1.set(key, cars[key])
})

// ES2017
const map = new Map(Object.entries(cars))

console.log(map)  // Map { 'BMW' => 3, 'Tesla' => 2, 'Toyota' => 1 }

String padding

用来格式化字符串

// 'someString'.padStart(numberOfCharcters [,stringForPadding]); 
'5'.padStart(10) // '          5'
'5'.padStart(10, '=*') //'=*=*=*=*=5'
'5'.padEnd(10) // '5         '
'5'.padEnd(10, '=*') //'5=*=*=*=*='

Object.getOwnPropertyDescriptors

Object.assign shallow copies all the details except getter and setter functions of the original source object.

var Car = {
 name: 'BMW',
 price: 1000000,
 set discount(x) {
  this.d = x;
 },
 get discount() {
  return this.d;
 },
};

//Print details of Car object's 'discount' property
console.log(Object.getOwnPropertyDescriptor(Car, 'discount'));
//prints..
// { 
//   get: [Function: get],
//   set: [Function: set],
//   enumerable: true,
//   configurable: true
// }

//Copy Car's properties to ElectricCar using Object.assign
const ElectricCar = Object.assign({}, Car);

//Print details of ElectricCar object's 'discount' property
console.log(Object.getOwnPropertyDescriptor(ElectricCar, 'discount'));
//prints..
// { 
//   value: undefined,
//   writable: true,
//   enumerable: true,
//   configurable: true 
// }
//⚠️Notice that getters and setters are missing in ElectricCar object 
// for 'discount' property !👎👎

//Copy Car's properties to ElectricCar2 using Object.defineProperties 
//and extract Car's properties using Object.getOwnPropertyDescriptors
const ElectricCar2 = Object.defineProperties({}, Object.getOwnPropertyDescriptors(Car));
//Print details of ElectricCar2 object's 'discount' property
console.log(Object.getOwnPropertyDescriptor(ElectricCar2, 'discount'));
//prints..
// { get: [Function: get],  👈🏼👈🏼👈🏼
//   set: [Function: set],  👈🏼👈🏼👈🏼
//   enumerable: true,
//   configurable: true 
// }
// Notice that getters and setters are present in the ElectricCar2 object 
//for 'discount' property!

Add trailing commas in the function parameters

This is a minor update that allows us to have trailing commas after the last function parameter. Why? To help with tools like git blame to ensure only new developers get blamed.

在函数定义时或者调用时均可以在最后一个参数后面添加逗号

Async / Await

重点讲下如何处理 Async / Await 的错误

//Option 1 - Use try catch within the function
async function doubleAndAdd(a, b) {
 try {
  a = await doubleAfter1Sec(a);
  b = await doubleAfter1Sec(b);
 } catch (e) {
  return NaN; //return something
 }
return a + b;
}
//🚀Usage:
doubleAndAdd('one', 2).then(console.log); // NaN
doubleAndAdd(1, 2).then(console.log); // 6
function doubleAfter1Sec(param) {
 return new Promise((resolve, reject) => {
  setTimeout(function() {
   let val = param * 2;
   isNaN(val) ? reject(NaN) : resolve(val);
  }, 1000);
 });
}
//Option 2 - *Catch* errors on  every await line
//as each await expression is a Promise in itself
async function doubleAndAdd(a, b) {
 a = await doubleAfter1Sec(a).catch(e => console.log('"a" is NaN')); // 👈
 b = await doubleAfter1Sec(b).catch(e => console.log('"b" is NaN')); // 👈
 if (!a || !b) {
  return NaN;
 }
 return a + b;
}
//🚀Usage:
doubleAndAdd('one', 2).then(console.log); // NaN  and logs:  "a" is NaN
doubleAndAdd(1, 2).then(console.log); // 6
function doubleAfter1Sec(param) {
 return new Promise((resolve, reject) => {
  setTimeout(function() {
   let val = param * 2;
   isNaN(val) ? reject(NaN) : resolve(val);
  }, 1000);
 });
}
//Option 3 - Dont do anything but handle outside the function
//since async / await returns a promise, we can catch the whole function's error
async function doubleAndAdd(a, b) {
 a = await doubleAfter1Sec(a);
 b = await doubleAfter1Sec(b);
 return a + b;
}
//🚀Usage:
doubleAndAdd('one', 2)
.then(console.log)
.catch(console.log); // 👈👈🏼<------- use "catch"
function doubleAfter1Sec(param) {
 return new Promise((resolve, reject) => {
  setTimeout(function() {
   let val = param * 2;
   isNaN(val) ? reject(NaN) : resolve(val);
  }, 1000);
 });
}
evantianx commented 6 years ago

ECMAScript 2018

Shared memory and atomics

The main idea is to bring some sort of multi-threading feature to JavaScript so that JS developers can write high-performance, concurrent programs in the future by allowing to manage memory by themselves instead of letting JS engine manage memory.

A cartoon intro to SharedArrayBuffers Articles

“dotall” flag for Regular expression

Currently in RegEx, although the dot(“.”) is supposed to match a single character, it doesn’t match new line characters like \n \r \f etc.

//Before
/first.second/.test('first\nsecond'); //false
//ECMAScript 2018
/first.second/s.test('first\nsecond'); //true   Notice: /s 👈🏼

RegExp Named Group Captures

1_1orizapmhp_sv5gvovt2wa 1_o6i-gxhbifd27qd73sw7ta 1_webly9caxfnwnwuqcwnmag

对象展开符 ... / 其余参数符 ...

the spread operator is used in the right side of the equals sign. The rest are used in the left-side of the equals sign.

RegExp Lookbehind Assertions(正则中的后顾)

1_1orizapmhp_sv5gvovt2wa 1_e1n-waowbc3yklrfcizxsa

Promise.prototype.finally()

The finally callback is called without any value and is always executed no matter what.

Asynchronous Iteration

const promise = [
  new Promise(resolve => resolve(1)),
  new Promise(resolve => resolve(2)),
  new Promise(resolve => resolve(3))
]
async function test() {
  for await (const obj of promises) {
    console.log(obj)
  }
}

test()  // 1, 2, 3