ES6剃法、ES7、ES8學(xué)習(xí)指南

期待已久的新課上線啦!解鎖React Native開(kāi)發(fā)新姿勢(shì),一網(wǎng)打盡React Native最新與最熱技術(shù)岭皂,點(diǎn)我Get!!!

概述

ES全稱ECMAScript,ECMAScript是ECMA制定的標(biāo)準(zhǔn)化腳本語(yǔ)言沼头。目前JavaScript使用的ECMAScript版本為ECMAScript-262爷绘。

ECMAScript 標(biāo)準(zhǔn)建立在一些原有的技術(shù)上,最為著名的是 JavaScript (網(wǎng)景) 和 JScript (微軟)进倍。它最初由網(wǎng)景的 Brendan Eich 發(fā)明土至,第一次出現(xiàn)是在網(wǎng)景的 Navigator 2.0 瀏覽器上。Netscape 2.0 以及微軟 Internet Explorer 3.0 后序的所有瀏覽器上都有它的身影猾昆。

ECMAScript版本 發(fā)布時(shí)間 新增特性
ECMAScript 2009(ES5) 2009年11月 擴(kuò)展了Object陶因、Array、Function的功能等
ECMAScript 2015(ES6) 2015年6月 類垂蜗,模塊化楷扬,箭頭函數(shù),函數(shù)參數(shù)默認(rèn)值等
ECMAScript 2016(ES7) 2016年3月 includes贴见,指數(shù)操作符
ECMAScript 2017(ES8) 2017年6月 sync/await毅否,Object.values(),Object.entries()蝇刀,String padding等

了解這些特性,不僅能使我們的編碼更加的符合規(guī)范徘溢,而且能提高我們Coding的效率吞琐。

ES6的特性

ES6的特性比較多,在 ES5 發(fā)布近 6 年(2009-11 至 2015-6)之后才將其標(biāo)準(zhǔn)化然爆。兩個(gè)發(fā)布版本之間時(shí)間跨度很大站粟,所以ES6中的特性比較多。

在這里列舉幾個(gè)常用的:

  • 模塊化
  • 箭頭函數(shù)
  • 函數(shù)參數(shù)默認(rèn)值
  • 模板字符串
  • 解構(gòu)賦值
  • 延展操作符
  • 對(duì)象屬性簡(jiǎn)寫(xiě)
  • Promise
  • Let與Const

1.類(class)

對(duì)熟悉Java曾雕,object-c奴烙,c#等純面向?qū)ο笳Z(yǔ)言的開(kāi)發(fā)者來(lái)說(shuō),都會(huì)對(duì)class有一種特殊的情懷剖张。ES6 引入了class(類)切诀,讓JavaScript的面向?qū)ο缶幊套兊酶雍?jiǎn)單和易于理解。

  class Animal {
    // 構(gòu)造函數(shù)搔弄,實(shí)例化的時(shí)候?qū)?huì)被調(diào)用幅虑,如果不指定,那么會(huì)有一個(gè)不帶參數(shù)的默認(rèn)構(gòu)造函數(shù).
    constructor(name,color) {
      this.name = name;
      this.color = color;
    }
    // toString 是原型對(duì)象上的屬性
    toString() {
      console.log('name:' + this.name + ',color:' + this.color);

    }
  }

 var animal = new Animal('dog','white');//實(shí)例化Animal
 animal.toString();

 console.log(animal.hasOwnProperty('name')); //true
 console.log(animal.hasOwnProperty('toString')); // false
 console.log(animal.__proto__.hasOwnProperty('toString')); // true

 class Cat extends Animal {
  constructor(action) {
    // 子類必須要在constructor中指定super 函數(shù)顾犹,否則在新建實(shí)例的時(shí)候會(huì)報(bào)錯(cuò).
    // 如果沒(méi)有置頂consructor,默認(rèn)帶super函數(shù)的constructor將會(huì)被添加倒庵、
    super('cat','white');
    this.action = action;
  }
  toString() {
    console.log(super.toString());
  }
 }

 var cat = new Cat('catch')
 cat.toString();

 // 實(shí)例cat 是 Cat 和 Animal 的實(shí)例褒墨,和Es5完全一致。
 console.log(cat instanceof Cat); // true
 console.log(cat instanceof Animal); // true

2.模塊化(Module)

ES5不支持原生的模塊化擎宝,在ES6中模塊作為重要的組成部分被添加進(jìn)來(lái)郁妈。模塊的功能主要由 export 和 import 組成。每一個(gè)模塊都有自己?jiǎn)为?dú)的作用域绍申,模塊之間的相互調(diào)用關(guān)系是通過(guò) export 來(lái)規(guī)定模塊對(duì)外暴露的接口噩咪,通過(guò)import來(lái)引用其它模塊提供的接口。同時(shí)還為模塊創(chuàng)造了命名空間失晴,防止函數(shù)的命名沖突剧腻。

導(dǎo)出(export)

ES6允許在一個(gè)模塊中使用export來(lái)導(dǎo)出多個(gè)變量或函數(shù)。

導(dǎo)出變量

//test.js
export var name = 'Rainbow'

心得:ES6不僅支持變量的導(dǎo)出涂屁,也支持常量的導(dǎo)出书在。 export const sqrt = Math.sqrt;//導(dǎo)出常量

ES6將一個(gè)文件視為一個(gè)模塊,上面的模塊通過(guò) export 向外輸出了一個(gè)變量拆又。一個(gè)模塊也可以同時(shí)往外面輸出多個(gè)變量儒旬。

 //test.js
 var name = 'Rainbow';
 var age = '24';
 export {name, age};

導(dǎo)出函數(shù)

// myModule.js
export function myModule(someArg) {
  return someArg;
}  

導(dǎo)入(import)

定義好模塊的輸出以后就可以在另外一個(gè)模塊通過(guò)import引用。

import {myModule} from 'myModule';// main.js
import {name,age} from 'test';// test.js

心得:一條import 語(yǔ)句可以同時(shí)導(dǎo)入默認(rèn)函數(shù)和其它變量帖族。import defaultMethod, { otherMethod } from 'xxx.js';

3.箭頭(Arrow)函數(shù)

這是ES6中最令人激動(dòng)的特性之一栈源。=>不只是關(guān)鍵字function的簡(jiǎn)寫(xiě),它還帶來(lái)了其它好處竖般。箭頭函數(shù)與包圍它的代碼共享同一個(gè)this,能幫你很好的解決this的指向問(wèn)題甚垦。有經(jīng)驗(yàn)的JavaScript開(kāi)發(fā)者都熟悉諸如var self = this;var that = this這種引用外圍this的模式。但借助=>涣雕,就不需要這種模式了艰亮。

箭頭函數(shù)的結(jié)構(gòu)

箭頭函數(shù)的箭頭=>之前是一個(gè)空括號(hào)、單個(gè)的參數(shù)名挣郭、或用括號(hào)括起的多個(gè)參數(shù)名迄埃,而箭頭之后可以是一個(gè)表達(dá)式(作為函數(shù)的返回值),或者是用花括號(hào)括起的函數(shù)體(需要自行通過(guò)return來(lái)返回值兑障,否則返回的是undefined)侄非。

// 箭頭函數(shù)的例子
()=>1
v=>v+1
(a,b)=>a+b
()=>{
    alert("foo");
}
e=>{
    if (e == 0){
        return 0;
    }
    return 1000/e;
}

心得:不論是箭頭函數(shù)還是bind,每次被執(zhí)行都返回的是一個(gè)新的函數(shù)引用流译,因此如果你還需要函數(shù)的引用去做一些別的事情(譬如卸載監(jiān)聽(tīng)器)逞怨,那么你必須自己保存這個(gè)引用。

卸載監(jiān)聽(tīng)器時(shí)的陷阱

錯(cuò)誤的做法

class PauseMenu extends React.Component{
    componentWillMount(){
        AppStateIOS.addEventListener('change', this.onAppPaused.bind(this));
    }
    componentWillUnmount(){
        AppStateIOS.removeEventListener('change', this.onAppPaused.bind(this));
    }
    onAppPaused(event){
    }
}

正確的做法

class PauseMenu extends React.Component{
    constructor(props){
        super(props);
        this._onAppPaused = this.onAppPaused.bind(this);
    }
    componentWillMount(){
        AppStateIOS.addEventListener('change', this._onAppPaused);
    }
    componentWillUnmount(){
        AppStateIOS.removeEventListener('change', this._onAppPaused);
    }
    onAppPaused(event){
    }
}

除上述的做法外先蒋,我們還可以這樣做:

class PauseMenu extends React.Component{
    componentWillMount(){
        AppStateIOS.addEventListener('change', this.onAppPaused);
    }
    componentWillUnmount(){
        AppStateIOS.removeEventListener('change', this.onAppPaused);
    }
    onAppPaused = (event) => {
        //把函數(shù)直接作為一個(gè)arrow function的屬性來(lái)定義骇钦,初始化的時(shí)候就綁定好了this指針
    }
}

需要注意的是:不論是bind還是箭頭函數(shù),每次被執(zhí)行都返回的是一個(gè)新的函數(shù)引用竞漾,因此如果你還需要函數(shù)的引用去做一些別的事情(譬如卸載監(jiān)聽(tīng)器)眯搭,那么你必須自己保存這個(gè)引用窥翩。

4.函數(shù)參數(shù)默認(rèn)值

ES6支持在定義函數(shù)的時(shí)候?yàn)槠湓O(shè)置默認(rèn)值:

function foo(height = 50, color = 'red')
{
    // ...
}

不使用默認(rèn)值:

function foo(height, color)
{
    var height = height || 50;
    var color = color || 'red';
    //...
}

這樣寫(xiě)一般沒(méi)問(wèn)題,但當(dāng)參數(shù)的布爾值為false時(shí)鳞仙,就會(huì)有問(wèn)題了寇蚊。比如,我們這樣調(diào)用foo函數(shù):

foo(0, "")

因?yàn)?code>0的布爾值為false棍好,這樣height的取值將是50仗岸。同理color的取值為‘red’。

所以說(shuō)借笙,函數(shù)參數(shù)默認(rèn)值不僅能是代碼變得更加簡(jiǎn)潔而且能規(guī)避一些問(wèn)題扒怖。

5.模板字符串

ES6支持模板字符串,使得字符串的拼接更加的簡(jiǎn)潔业稼、直觀盗痒。

不使用模板字符串:

var name = 'Your name is ' + first + ' ' + last + '.'

使用模板字符串:

var name = `Your name is ${first} ${last}.`

在ES6中通過(guò)${}就可以完成字符串的拼接,只需要將變量放在大括號(hào)之中低散。

6.解構(gòu)賦值

解構(gòu)賦值語(yǔ)法是JavaScript的一種表達(dá)式俯邓,可以方便的從數(shù)組或者對(duì)象中快速提取值賦給定義的變量。

獲取數(shù)組中的值

從數(shù)組中獲取值并賦值到變量中熔号,變量的順序與數(shù)組中對(duì)象順序?qū)?yīng)稽鞭。

var foo = ["one", "two", "three", "four"];

var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"

//如果你要忽略某些值,你可以按照下面的寫(xiě)法獲取你想要的值
var [first, , , last] = foo;
console.log(first); // "one"
console.log(last); // "four"

//你也可以這樣寫(xiě)
var a, b; //先聲明變量

[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2

如果沒(méi)有從數(shù)組中的獲取到值引镊,你可以為變量設(shè)置一個(gè)默認(rèn)值朦蕴。

var a, b;

[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7

通過(guò)解構(gòu)賦值可以方便的交換兩個(gè)變量的值。

var a = 1;
var b = 3;

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1

獲取對(duì)象中的值

const student = {
  name:'Ming',
  age:'18',
  city:'Shanghai'  
};

const {name,age,city} = student;
console.log(name); // "Ming"
console.log(age); // "18"
console.log(city); // "Shanghai"

7.延展操作符(Spread operator)

延展操作符...可以在函數(shù)調(diào)用/數(shù)組構(gòu)造時(shí), 將數(shù)組表達(dá)式或者string在語(yǔ)法層面展開(kāi)弟头;還可以在構(gòu)造對(duì)象時(shí), 將對(duì)象表達(dá)式按key-value的方式展開(kāi)梦重。

語(yǔ)法

函數(shù)調(diào)用:

myFunction(...iterableObj);

數(shù)組構(gòu)造或字符串:

[...iterableObj, '4', ...'hello', 6];

構(gòu)造對(duì)象時(shí),進(jìn)行克隆或者屬性拷貝(ECMAScript 2018規(guī)范新增特性):

let objClone = { ...obj };

應(yīng)用場(chǎng)景

在函數(shù)調(diào)用時(shí)使用延展操作符

function sum(x, y, z) {
  return x + y + z;
}
const numbers = [1, 2, 3];

//不使用延展操作符
console.log(sum.apply(null, numbers));

//使用延展操作符
console.log(sum(...numbers));// 6

構(gòu)造數(shù)組

沒(méi)有展開(kāi)語(yǔ)法的時(shí)候,只能組合使用 push亮瓷,splice,concat 等方法降瞳,來(lái)將已有數(shù)組元素變成新數(shù)組的一部分嘱支。有了展開(kāi)語(yǔ)法, 構(gòu)造新數(shù)組會(huì)變得更簡(jiǎn)單、更優(yōu)雅:

const stuendts = ['Jine','Tom']; 
const persons = ['Tony',... stuendts,'Aaron','Anna'];
conslog.log(persions)// ["Tony", "Jine", "Tom", "Aaron", "Anna"]

和參數(shù)列表的展開(kāi)類似, ... 在構(gòu)造字?jǐn)?shù)組時(shí), 可以在任意位置多次使用挣饥。

數(shù)組拷貝

var arr = [1, 2, 3];
var arr2 = [...arr]; // 等同于 arr.slice()
arr2.push(4); 
console.log(arr2)//[1, 2, 3, 4]

展開(kāi)語(yǔ)法和 Object.assign() 行為一致, 執(zhí)行的都是淺拷貝(只遍歷一層)除师。

連接多個(gè)數(shù)組

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
var arr3 = [...arr1, ...arr2];// 將 arr2 中所有元素附加到 arr1 后面并返回
//等同于
var arr4 = arr1.concat(arr2);

在ECMAScript 2018中延展操作符增加了對(duì)對(duì)象的支持

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };

var clonedObj = { ...obj1 };
// 克隆后的對(duì)象: { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// 合并后的對(duì)象: { foo: "baz", x: 42, y: 13 }

在React中的應(yīng)用

通常我們?cè)诜庋b一個(gè)組件時(shí),會(huì)對(duì)外公開(kāi)一些 props 用于實(shí)現(xiàn)功能扔枫。大部分情況下在外部使用都應(yīng)顯示的傳遞 props 汛聚。但是當(dāng)傳遞大量的props時(shí),會(huì)非常繁瑣短荐,這時(shí)我們可以使用 ...(延展操作符,用于取出參數(shù)對(duì)象的所有可遍歷屬性) 來(lái)進(jìn)行傳遞倚舀。

一般情況下我們應(yīng)該這樣寫(xiě)

<CustomComponent name ='Jine' age ={21} />

使用 ... 叹哭,等同于上面的寫(xiě)法

const params = {
        name: 'Jine',
        age: 21
    }

<CustomComponent {...params} />

配合解構(gòu)賦值避免傳入一些不需要的參數(shù)

var params = {
    name: '123',
    title: '456',
    type: 'aaa'
}

var { type, ...other } = params;

<CustomComponent type='normal' number={2} {...other} />
//等同于
<CustomComponent type='normal' number={2} name='123' title='456' />

8.對(duì)象屬性簡(jiǎn)寫(xiě)

在ES6中允許我們?cè)谠O(shè)置一個(gè)對(duì)象的屬性的時(shí)候不指定屬性名。

不使用ES6

const name='Ming',age='18',city='Shanghai';
        
const student = {
    name:name,
    age:age,
    city:city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}

對(duì)象中必須包含屬性和值痕貌,顯得非常冗余风罩。

使用ES6

const name='Ming',age='18',city='Shanghai';
        
const student = {
    name,
    age,
    city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}

對(duì)象中直接寫(xiě)變量,非常簡(jiǎn)潔舵稠。

9.Promise

Promise 是異步編程的一種解決方案超升,比傳統(tǒng)的解決方案callback更加的優(yōu)雅。它最早由社區(qū)提出和實(shí)現(xiàn)的哺徊,ES6 將其寫(xiě)進(jìn)了語(yǔ)言標(biāo)準(zhǔn)室琢,統(tǒng)一了用法,原生提供了Promise對(duì)象落追。

不使用ES6

嵌套兩個(gè)setTimeout回調(diào)函數(shù):

setTimeout(function()
{
    console.log('Hello'); // 1秒后輸出"Hello"
    setTimeout(function()
    {
        console.log('Hi'); // 2秒后輸出"Hi"
    }, 1000);
}, 1000);

使用ES6

var waitSecond = new Promise(function(resolve, reject)
{
    setTimeout(resolve, 1000);
});

waitSecond
    .then(function()
    {
        console.log("Hello"); // 1秒后輸出"Hello"
        return waitSecond;
    })
    .then(function()
    {
        console.log("Hi"); // 2秒后輸出"Hi"
    });

上面的的代碼使用兩個(gè)then來(lái)進(jìn)行異步編程串行化盈滴,避免了回調(diào)地獄:

10.支持let與const

在之前JS是沒(méi)有塊級(jí)作用域的,const與let填補(bǔ)了這方便的空白淋硝,const與let都是塊級(jí)作用域雹熬。

使用var定義的變量為函數(shù)級(jí)作用域:

{
  var a = 10;
}

console.log(a); // 輸出10

使用let與const定義的變量為塊級(jí)作用域:

{
  let a = 10;
}

console.log(a); //-1 or Error“ReferenceError: a is not defined”

ES7的特性

在ES6之后,ES的發(fā)布頻率更加頻繁谣膳,基本每年一次竿报,所以自ES6之后,每個(gè)新版本的特性的數(shù)量就比較少继谚。

  • includes()
  • 指數(shù)操作符

1. Array.prototype.includes()

includes() 函數(shù)用來(lái)判斷一個(gè)數(shù)組是否包含一個(gè)指定的值烈菌,如果包含則返回 true,否則返回false花履。

includes 函數(shù)與 indexOf 函數(shù)很相似芽世,下面兩個(gè)表達(dá)式是等價(jià)的:

arr.includes(x)
arr.indexOf(x) >= 0

接下來(lái)我們來(lái)判斷數(shù)字中是否包含某個(gè)元素:

在ES7之前的做法

使用indexOf()驗(yàn)證數(shù)組中是否存在某個(gè)元素,這時(shí)需要根據(jù)返回值是否為-1來(lái)判斷:

let arr = ['react', 'angular', 'vue'];

if (arr.indexOf('react') !== -1)
{
    console.log('react存在');
}

使用ES7的includes()

使用includes()驗(yàn)證數(shù)組中是否存在某個(gè)元素诡壁,這樣更加直觀簡(jiǎn)單:

let arr = ['react', 'angular', 'vue'];

if (arr.includes('react'))
{
    console.log('react存在');
}

2.指數(shù)操作符

在ES7中引入了指數(shù)運(yùn)算符**济瓢,**具有與Math.pow(..)等效的計(jì)算結(jié)果。

不使用指數(shù)操作符

使用自定義的遞歸函數(shù)calculateExponent或者M(jìn)ath.pow()進(jìn)行指數(shù)運(yùn)算:

function calculateExponent(base, exponent)
{
    if (exponent === 1)
    {
        return base;
    }
    else
    {
        return base * calculateExponent(base, exponent - 1);
    }
}

console.log(calculateExponent(2, 10)); // 輸出1024
console.log(Math.pow(2, 10)); // 輸出1024

使用指數(shù)操作符

使用指數(shù)運(yùn)算符**妹卿,就像+旺矾、-等操作符一樣:

console.log(2**10);// 輸出1024

ES8的特性

  • async/await
  • Object.values()
  • Object.entries()
  • String padding
  • 函數(shù)參數(shù)列表結(jié)尾允許逗號(hào)
  • Object.getOwnPropertyDescriptors()

瀏覽器兼容性

1.async/await

在ES8中加入了對(duì)async/await的支持,也就我們所說(shuō)的異步函數(shù)夺克,這是一個(gè)很實(shí)用的功能箕宙。 async/await將我們從頭痛的回調(diào)地獄中解脫出來(lái)了,使整個(gè)代碼看起來(lái)很簡(jiǎn)潔铺纽。

使用async/await與不使用async/await的差別:

login(userName) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('1001');
        }, 600);
    });
}

getData(userId) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (userId === '1001') {
                resolve('Success');
            } else {
                reject('Fail');
            }
        }, 600);
    });
}

// 不使用async/await ES7
doLogin(userName) {
    this.login(userName)
        .then(this.getData)
        .then(result => {
            console.log(result)
        })
}

// 使用async/await ES8
async doLogin2(userName) {
    const userId=await this.login(userName);
    const result=await this.getData(userId);
}

this.doLogin()// Success
this.doLogin2()// Success

async/await的幾種應(yīng)用場(chǎng)景

接下來(lái)我們來(lái)看一下async/await的幾種應(yīng)用場(chǎng)景柬帕。

獲取異步函數(shù)的返回值

異步函數(shù)本身會(huì)返回一個(gè)Promise,所以我們可以通過(guò)then來(lái)獲取異步函數(shù)的返回值。

async function charCountAdd(data1, data2) {
    const d1=await charCount(data1);
    const d2=await charCount(data2);
    return d1+d2;
}
charCountAdd('Hello','Hi').then(console.log);//通過(guò)then獲取異步函數(shù)的返回值陷寝。
function charCount(data) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(data.length);
        }, 1000);
    });
}

async/await在并發(fā)場(chǎng)景中的應(yīng)用

對(duì)于上述的例子锅很,我們調(diào)用await兩次,每次都是等待1秒一共是2秒盼铁,效率比較低粗蔚,而且兩次await的調(diào)用并沒(méi)有依賴關(guān)系,那能不能讓其并發(fā)執(zhí)行呢饶火,答案是可以的鹏控,接下來(lái)我們通過(guò)Promise.all來(lái)實(shí)現(xiàn)await的并發(fā)調(diào)用。

async function charCountAdd(data1, data2) {
    const [d1,d2]=await Promise.all([charCount(data1),charCount(data2)]);
    return d1+d2;
}
charCountAdd('Hello','Hi').then(console.log);
function charCount(data) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(data.length);
        }, 1000);
    });
}

通過(guò)上述代碼我們實(shí)現(xiàn)了兩次charCount的并發(fā)調(diào)用肤寝,Promise.all接受的是一個(gè)數(shù)組当辐,它可以將數(shù)組中的promise對(duì)象并發(fā)執(zhí)行;

async/await的幾種錯(cuò)誤處理方式

第一種:捕捉整個(gè)async/await函數(shù)的錯(cuò)誤

async function charCountAdd(data1, data2) {
    const d1=await charCount(data1);
    const d2=await charCount(data2);
    return d1+d2;
}
charCountAdd('Hello','Hi')
    .then(console.log)
    .catch(console.log);//捕捉整個(gè)async/await函數(shù)的錯(cuò)誤
...

這種方式可以捕捉整個(gè)charCountAdd運(yùn)行過(guò)程中出現(xiàn)的錯(cuò)誤鲤看,錯(cuò)誤可能是由charCountAdd本身產(chǎn)生的缘揪,也可能是由對(duì)data1的計(jì)算中或data2的計(jì)算中產(chǎn)生的。

第二種:捕捉單個(gè)的await表達(dá)式的錯(cuò)誤

async function charCountAdd(data1, data2) {
    const d1=await charCount(data1)
        .catch(e=>console.log('d1 is null'));
    const d2=await charCount(data2)
        .catch(e=>console.log('d2 is null'));
    return d1+d2;
}
charCountAdd('Hello','Hi').then(console.log);

通過(guò)這種方式可以捕捉每一個(gè)await表達(dá)式的錯(cuò)誤义桂,如果既要捕捉每一個(gè)await表達(dá)式的錯(cuò)誤找筝,又要捕捉整個(gè)charCountAdd函數(shù)的錯(cuò)誤,可以在調(diào)用charCountAdd的時(shí)候加個(gè)catch慷吊。

...
charCountAdd('Hello','Hi')
    .then(console.log)
    .catch(console.log);//捕捉整個(gè)async/await函數(shù)的錯(cuò)誤
...

第三種:同時(shí)捕捉多個(gè)的await表達(dá)式的錯(cuò)誤

async function charCountAdd(data1, data2) {
    let d1,d2;
    try {
        d1=await charCount(data1);
        d2=await charCount(data2);
    }catch (e){
        console.log('d1 is null');
    }
    return d1+d2;
}
charCountAdd('Hello','Hi')
    .then(console.log);

function charCount(data) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(data.length);
        }, 1000);
    });
}

2.Object.values()

Object.values()是一個(gè)與Object.keys()類似的新函數(shù)袖裕,但返回的是Object自身屬性的所有值,不包括繼承的值溉瓶。

假設(shè)我們要遍歷如下對(duì)象obj的所有值:

const obj = {a: 1, b: 2, c: 3};

不使用Object.values() :ES7

const vals=Object.keys(obj).map(key=>obj[key]);
console.log(vals);//[1, 2, 3]

使用Object.values() :ES8

const values=Object.values(obj1);
console.log(values);//[1, 2, 3]

從上述代碼中可以看出Object.values()為我們省去了遍歷key急鳄,并根據(jù)這些key獲取value的步驟。

3.Object.entries

Object.entries()函數(shù)返回一個(gè)給定對(duì)象自身可枚舉屬性的鍵值對(duì)的數(shù)組堰酿。

接下來(lái)我們來(lái)遍歷上文中的obj對(duì)象的所有屬性的key和value:

不使用Object.entries() :ES7

Object.keys(obj).forEach(key=>{
    console.log('key:'+key+' value:'+obj[key]);
})
//key:a value:1
//key:b value:2
//key:c value:3

使用Object.entries() :ES8

for(let [key,value] of Object.entries(obj1)){
    console.log(`key: ${key} value:${value}`)
}
//key:a value:1
//key:b value:2
//key:c value:3

4.String padding

在ES8中String新增了兩個(gè)實(shí)例函數(shù)String.prototype.padStartString.prototype.padEnd疾宏,允許將空字符串或其他字符串添加到原始字符串的開(kāi)頭或結(jié)尾。

String.padStart(targetLength,[padString])

  • targetLength:當(dāng)前字符串需要填充到的目標(biāo)長(zhǎng)度触创。如果這個(gè)數(shù)值小于當(dāng)前字符串的長(zhǎng)度坎藐,則返回當(dāng)前字符串本身。
  • padString:(可選)填充字符串哼绑。如果字符串太長(zhǎng)顺饮,使填充后的字符串長(zhǎng)度超過(guò)了目標(biāo)長(zhǎng)度,則只保留最左側(cè)的部分凌那,其他部分會(huì)被截?cái)啵藚?shù)的缺省值為 " "吟逝。
console.log('0.0'.padStart(4,'10')) //10.0
console.log('0.0'.padStart(20))//                0.00    

String.padEnd(targetLength,padString])

  • targetLength:當(dāng)前字符串需要填充到的目標(biāo)長(zhǎng)度帽蝶。如果這個(gè)數(shù)值小于當(dāng)前字符串的長(zhǎng)度,則返回當(dāng)前字符串本身。
  • padString:(可選) 填充字符串励稳。如果字符串太長(zhǎng)佃乘,使填充后的字符串長(zhǎng)度超過(guò)了目標(biāo)長(zhǎng)度,則只保留最左側(cè)的部分驹尼,其他部分會(huì)被截?cái)嗳け埽藚?shù)的缺省值為 " ";
console.log('0.0'.padEnd(4,'0')) //0.00    
console.log('0.0'.padEnd(10,'0'))//0.00000000

4.函數(shù)參數(shù)列表結(jié)尾允許逗號(hào)

這是一個(gè)不痛不癢的更新新翎,主要作用是方便使用git進(jìn)行多人協(xié)作開(kāi)發(fā)時(shí)修改同一個(gè)函數(shù)減少不必要的行變更程帕。

不使用ES8

//程序員A
var f = function(a,
  b
   ) { 
  ...
  }

//程序員B
var f = function(a,
  b,   //變更行
  c   //變更行
   ) { 
  ...
  }

//程序員C
var f = function(a,
  b,
  c,   //變更行
  d   //變更行
   ) { 
  ...
  }

使用ES8

//程序員A
var f = function(a,
  b,
   ) { 
  ...
  }

//程序員B
var f = function(a,
  b,
  c,   //變更行
   ) { 
  ...
  }

//程序員C
var f = function(a,
  b,
  c,
  d,   //變更行
   ) { 
  ...
  }

5.Object.getOwnPropertyDescriptors()

Object.getOwnPropertyDescriptors()函數(shù)用來(lái)獲取一個(gè)對(duì)象的所有自身屬性的描述符,如果沒(méi)有任何自身屬性,則返回空對(duì)象地啰。

函數(shù)原型:

Object.getOwnPropertyDescriptors(obj)

返回obj對(duì)象的所有自身屬性的描述符愁拭,如果沒(méi)有任何自身屬性,則返回空對(duì)象亏吝。

const obj2 = {
    name: 'Jine',
    get age() { return '18' }
};
Object.getOwnPropertyDescriptors(obj2)
// {
//   age: {
//     configurable: true,
//     enumerable: true,
//     get: function age(){}, //the getter function
//     set: undefined
//   },
//   name: {
//     configurable: true,
//     enumerable: true,
//      value:"Jine",
//      writable:true
//   }
// }

總結(jié)

技術(shù)更替的車(chē)輪一直在前進(jìn)中岭埠,JavaScript的規(guī)范和標(biāo)準(zhǔn)也在不斷的制定和完善。你會(huì)發(fā)現(xiàn)ECMAScript 新版的很多特性已經(jīng)是Typescript蔚鸥,瀏覽器或其他polyfills的一部分惜论,就拿ES8的async/await來(lái)說(shuō),它是2017年6月被納入ECMAScript的止喷,但我在2016年的時(shí)候就已經(jīng)開(kāi)始使用這個(gè)特性了馆类,這些特性通常由ECMAScript議員提交,然后會(huì)出現(xiàn)在在未來(lái)的某個(gè)ECMAScript版本中启盛。

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蹦掐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子僵闯,更是在濱河造成了極大的恐慌卧抗,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鳖粟,死亡現(xiàn)場(chǎng)離奇詭異社裆,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)向图,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)泳秀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人榄攀,你說(shuō)我怎么就攤上這事嗜傅。” “怎么了檩赢?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵吕嘀,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)偶房,這世上最難降的妖魔是什么趁曼? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮棕洋,結(jié)果婚禮上挡闰,老公的妹妹穿的比我還像新娘。我一直安慰自己掰盘,他們只是感情好摄悯,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著庆杜,像睡著了一般射众。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上晃财,一...
    開(kāi)封第一講書(shū)人閱讀 51,698評(píng)論 1 305
  • 那天叨橱,我揣著相機(jī)與錄音,去河邊找鬼断盛。 笑死罗洗,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的钢猛。 我是一名探鬼主播伙菜,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼命迈!你這毒婦竟也來(lái)了贩绕?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤壶愤,失蹤者是張志新(化名)和其女友劉穎淑倾,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體征椒,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡娇哆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了勃救。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碍讨。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蒙秒,靈堂內(nèi)的尸體忽然破棺而出勃黍,到底是詐尸還是另有隱情,我是刑警寧澤晕讲,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布覆获,位于F島的核電站榜田,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏锻梳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一净捅、第九天 我趴在偏房一處隱蔽的房頂上張望疑枯。 院中可真熱鬧,春花似錦蛔六、人聲如沸荆永。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)具钥。三九已至,卻和暖如春液兽,著一層夾襖步出監(jiān)牢的瞬間骂删,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工四啰, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宁玫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓柑晒,卻偏偏與公主長(zhǎng)得像欧瘪,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子匙赞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • ES7新特性 ES7在ES6的基礎(chǔ)上添加了三項(xiàng)內(nèi)容:求冪運(yùn)算符()佛掖、Array.prototype.include...
    吳佳浩閱讀 1,652評(píng)論 0 3
  • 一、ES6簡(jiǎn)介 ? 歷時(shí)將近6年的時(shí)間來(lái)制定的新 ECMAScript 標(biāo)準(zhǔn) ECMAScript 6(亦稱 ...
    一歲一枯榮_閱讀 6,078評(píng)論 8 25
  • 本文為阮一峰大神的《ECMAScript 6 入門(mén)》的個(gè)人版提純涌庭! babel babel負(fù)責(zé)將JS高級(jí)語(yǔ)法轉(zhuǎn)義芥被,...
    Devildi已被占用閱讀 1,985評(píng)論 0 4
  • 轉(zhuǎn)發(fā)了一篇關(guān)于比較中西方教育的文章,卻引起了朋友圈朋友的抓狂和質(zhì)疑:“這個(gè)文章讀了到底要表達(dá)什么觀點(diǎn)呢脾猛?是要提...
    筱荀閱讀 216評(píng)論 1 0
  • 吃飯撕彤、喝酒,以及 我曾經(jīng)愛(ài)過(guò)你 默默無(wú)聞猛拴,不知孤獨(dú) 與卑微地愛(ài)著你 愛(ài)情啊羹铅,你瞧它 多像一次殘留在人世間的 毫無(wú)指...
    野孤蟬閱讀 189評(píng)論 0 6