期待已久的新課上線啦!解鎖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.padStart
和String.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版本中启盛。