ES6簡(jiǎn)單總結(jié)(搭配簡(jiǎn)單的講解和小案例)2019-06-10

?

一 let和const

1.let

(1)一個(gè)大括號(hào)就是一個(gè)塊級(jí)作用域百侧,let聲明的變量只在自己作用域有效柬泽;

(2)es6強(qiáng)制開啟嚴(yán)格模式蛇耀,變量未聲明不能引用结闸,所以會(huì)報(bào) Uncaught ReferenceError

functiontest(){for(leti =1; i <3; i++) {console.log(i)? }console.log(i);// Uncaught ReferenceError: i is not defined}test();

(3)let不能重復(fù)聲明

functiontest(){leta =1;leta =2;}test();

(4)let不存在變量提升(這個(gè)地方有問題)

// var 的情況console.log(a);// 輸出undefinedvara =2;// let 的情況console.log(b);// 報(bào)錯(cuò)ReferenceErrorletb =2;

2.const

(1)const聲明之后必須賦值唇兑,否則會(huì)編譯不通過(guò);

(2)const聲明的值不允許修改桦锄;

constPI =3.14;// PI = 2;? // const PI;console.log(PI);

(3)const如果是對(duì)象的話扎附,可以向?qū)ο笾刑砑訉傩裕部梢孕薷腶的屬性结耀;json是指向內(nèi)存地址的一個(gè)指針留夜,指針的指向不變,但是那個(gè)被json指針?biāo)赶虻膬?nèi)存地址所存儲(chǔ)的內(nèi)容是可以變化的图甜;

constjson = {? a:2}json.a =3;json.b =3;console.log(json.a)//3console.log(json.b)//3

二 解構(gòu)賦值

1.基本用法

先上兩個(gè)例子了解什么是解構(gòu)賦值

{leta, b, rest;? [a, b, rest] = [1,2];console.log(a, b, rest);//1 2 undefined}

{leta, b, rest;? [a, b, ...rest] = [1,2,3,4,5,6,7];console.log(a, b, rest);//1 2 [3, 4, 5, 6, 7]}

2.對(duì)象的解構(gòu)賦值

{leta, b;? ({ a, b } = {a:1,b:2});//a香伴,b 順序不影響其結(jié)構(gòu)結(jié)果console.log(a, b);// 1 2}

3.默認(rèn)值

{leta, b, rest;? [a, b, rest =3] = [1,2];console.log(a, b, rest);// 1 2 3}

4.實(shí)際應(yīng)用

變量的交換

{leta =1;letb =2;? [a, b] = [b, a];console.log(a, b);//2 1}

接收函數(shù)返回的值

{functionf(){return[12,13];? }leta, b;? [a, b] = f();console.log(a, b);//12 13}{functionf(){return[12,13,14,15,16];? }leta, b;? [a, , , b] = f();//函數(shù)返回多個(gè)值,可以選擇性的接收對(duì)應(yīng)的值console.log(a, b);// 12 16}{functionf(){return[12,13,14,15,16];? }leta, b;? [a, , ...b] = f();//取出對(duì)應(yīng)的值具则,其他的值可以直接賦值給數(shù)據(jù)console.log(a, b);// 12 [14, 15, 16]}

5.對(duì)象的解構(gòu)賦值的應(yīng)用

{leto = {p:42,q:true};let{ p, q } = o;console.log(p, q);//42 true}{let{ a =10, b =11} = {a:3}// 對(duì)象的默認(rèn)值更改console.log(a,b);// 3, 11}

6.解構(gòu)賦值的簡(jiǎn)單應(yīng)用舉例

{letmetaData = {? ? title:'abc',test: [{? ? ? title:'gao',? ? ? desc:'description'}]? }let{ title: esTitle,test: [{ title: cnTitle }] } = metaData;? console.log(esTitle, cnTitle);}

三 正則的擴(kuò)展

1.構(gòu)造函數(shù)來(lái)創(chuàng)建正則

{letregex1 =newRegExp('xyz','i');letregex2 =newRegExp(/xyz/i);console.log(regex1.test('xyz123'), regex2.test('xyz123'));// true trueletregex3 =newRegExp(/xyz/ig,'i');// 后面的修飾符會(huì)把前面的修飾符給覆蓋掉console.log(regex3.flags);// es6新增的即纲,用來(lái)獲取正則表達(dá)式的修飾符}

2.g修飾符和y修飾符

y修飾符的作用與g修飾符類似,也是全局匹配博肋,后一次匹配都從上一次匹配成功的下一個(gè)位置開始低斋。不同之處在于蜂厅,g修飾符只要剩余位置中存在匹配就可,而y修飾符確保匹配必須從剩余的第一個(gè)位置開始膊畴。

{lets ='bbb_bb_b';leta1 =/b+/g;// g只要匹配到都算leta2 =/b+/y;// y必須是下一個(gè)開始的字母開始匹配console.log('one', a1.exec(s), a2.exec(s));// g修飾符匹配到都可以掘猿,y修飾符必須從第一個(gè)開始匹配,如果一第個(gè)不是b則會(huì)輸出nullconsole.log('two', a1.exec(s), a2.exec(s));// 第二次匹配唇跨,g修飾符會(huì)只要匹配到都可以稠通,y修飾符必須從緊鄰的下一個(gè)字符開始匹配console.log(a1.sticky, a2.sticky);// 判斷是否開啟了y修飾符? false true}

one和two的輸出結(jié)果

[圖片上傳失敗...(image-6b6ca8-1517308143359)]

3.u修飾符(unicode)

ES6 對(duì)正則表達(dá)式添加了u修飾符,含義為“Unicode模式”买猖,用來(lái)正確處理大于\uFFFF的 Unicode 字符改橘。

{console.log('u-1', /^\uD83D/.test('\uD83D\uDC2A'));// 不加u把后面的四個(gè)字節(jié)當(dāng)成兩個(gè)字符console.log('u-2', /^\uD83D/u.test('\uD83D\uDC2A'));// 加u把后面的4個(gè)字節(jié)當(dāng)作一個(gè)字符console.log(/\u{61}/.test('a'));// false 大括號(hào)括起來(lái)代表一個(gè)unicode字符,所以必須加u才能識(shí)別console.log(/\u{61}/u.test('a'));// trueconsole.log(`\u{20BB7}`);lets ='??';console.log('u-1', /^.$/.test(s));//false 字符串大于兩個(gè)字節(jié)玉控,必須加u修飾符才能匹配到console.log('u-2', /^.$/u.test(s));//trueconsole.log('test-1', /??{2}/.test('????'));// falseconsole.log('test-2', /??{2}/u.test('????'));// true}

四 字符串?dāng)U展

1.unicode的表示方法

{console.log('a','\u0061');// a aconsole.log('s','\u20BB7');// s ?7? 把前兩個(gè)字節(jié)當(dāng)作一個(gè)整體console.log('s','\u{20BB7}');// s ??? unicode編碼用{}可以正常識(shí)別}

2.codePointAt和charCodeAt的對(duì)比

對(duì)于4個(gè)字節(jié)的字符飞主,JavaScript不能正確處理,字符串長(zhǎng)度會(huì)誤判為2高诺,而且charAt方法無(wú)法讀取整個(gè)字符碌识,charCodeAt方法只能分別返回前兩個(gè)字節(jié)和后兩個(gè)字節(jié)的值。ES6提供了codePointAt方法虱而,能夠正確處理4個(gè)字節(jié)儲(chǔ)存的字符筏餐,返回一個(gè)字符的碼點(diǎn)。

{lets ='??';console.log(s.length);// 2console.log('0', s.charAt(0));// 0 ?? //es5未對(duì)多個(gè)字節(jié)的字符做處理console.log('1', s.charAt(1));// 1 ?console.log('at0', s.charCodeAt(0));//at0 55362console.log('at1', s.charCodeAt(1));//at1 57271lets1 ='??a';console.log('length', s1.length);// 3console.log('code0', s1.codePointAt(0));// code0 134071console.log('code0', s1.codePointAt(0).toString(16));// code0 es6會(huì)自動(dòng)把多個(gè)字節(jié)的字符當(dāng)作一個(gè)整體來(lái)處理 console.log('code1', s1.codePointAt(1));// code1 57271console.log('code2', s1.codePointAt(2));// code2 97}

3.fromCharCode和fromCodePoint

ES5提供String.fromCharCode方法牡拇,用于從碼點(diǎn)返回對(duì)應(yīng)字符胖烛,但是這個(gè)方法不能識(shí)別Unicode編號(hào)大于0xFFFF。ES6提供了String.fromCodePoint方法诅迷,可以識(shí)別大于0xFFFF的字符,彌補(bǔ)了String.fromCharCode方法的不足众旗。在作用上罢杉,正好與codePointAt方法相反。注意贡歧,fromCodePoint方法定義在String對(duì)象上滩租,而codePointAt方法定義在字符串的實(shí)例對(duì)象上。

{console.log(String.fromCharCode('0x20bb7'));//?console.log(String.fromCodePoint('0x20bb7'))//??}

4.字符串遍歷器

{// es5letstr ='\u{20bb7}abc';for(leti =0; i < str.length; i++) {console.log('es5', str[i]);//? ? a b c? }//es6for(letcodeofstr) {console.log('es6', code);// ?? a b c}}

5.一些常用的字符串a(chǎn)pi

{letstr ='string';console.log('includes', str.includes('c'));// 判斷是否包含? falseconsole.log('start', str.startsWith('s'));// 以什么開頭? trueconsole.log('end', str.endsWith('ng'));// 以什么結(jié)尾? trueconsole.log('repeat', str.repeat(2));// 字符串重復(fù)兩次? stringstring}

ES6 引入了字符串補(bǔ)全長(zhǎng)度的功能利朵。如果某個(gè)字符串不夠指定長(zhǎng)度律想,會(huì)在頭部或尾部補(bǔ)全。padStart()用于頭部補(bǔ)全绍弟,padEnd()用于尾部補(bǔ)全技即。如果原字符串的長(zhǎng)度,等于或大于指定的最小長(zhǎng)度樟遣,則返回原字符串而叼。如果用來(lái)補(bǔ)全的字符串與原字符串身笤,兩者的長(zhǎng)度之和超過(guò)了指定的最小長(zhǎng)度,則會(huì)截去超出位數(shù)的補(bǔ)全字符串葵陵。

{? ? console.log('1'.padStart(2,'0'));// 01console.log('1'.padEnd(2,'0'));// 10}

6.模板字符串

{letname ="List";letinfo ="hello world";letm =`i am${name}${info}`;console.log(m);//i am List hello world}

7.標(biāo)簽?zāi)0?/p>

{letuser = {name:'list',info:'hello world'}functionfn(s,v1,v2){console.log(s,v1,v2);returns+v1+v2;? }console.log(fn`i am${user.name}${user.info}`)// ``符號(hào)相當(dāng)于一個(gè)函數(shù)的參數(shù)fn(i am ${user.name} ${user.info});}

輸出結(jié)果

[圖片上傳失敗...(image-96cb9b-1517308143359)]

8.String.row API

ES6還為原生的String對(duì)象液荸,提供了一個(gè)raw方法。String.raw方法脱篙,往往用來(lái)充當(dāng)模板字符串的處理函數(shù)娇钱,返回一個(gè)斜杠都被轉(zhuǎn)義(即斜杠前面再加一個(gè)斜杠)的字符串,對(duì)應(yīng)于替換變量后的模板字符串绊困。

{console.log('raw '+String.raw`hi\n${1+2}`)console.log('noRaw '+`hi\n${1+2}`)}

輸出結(jié)果

[圖片上傳失敗...(image-fd3999-1517308143359)]

五 數(shù)值擴(kuò)展

1.二進(jìn)制八進(jìn)制表示法

從 ES5 開始文搂,在嚴(yán)格模式之中,八進(jìn)制就不再允許使用前綴0表示考抄,ES6進(jìn)一步明確细疚,要使用前綴0o表示。如果要將0b和0o前綴的字符串?dāng)?shù)值轉(zhuǎn)為十進(jìn)制川梅,要使用Number方法疯兼。

{? console.log('B',0b11010101010);//二進(jìn)制表示,b大小寫都可以console.log('O',0O1237637236);// 八進(jìn)制表示法}

2.Number.isFinite()和Number.isNaN()

Number.isFinite()用來(lái)判斷數(shù)字是否有限(無(wú)盡小數(shù))贫途,Number.isNaN()來(lái)判斷一個(gè)數(shù)是不是小數(shù)

{console.log('15',isFinite(15));//trueconsole.log('NaN',isFinite(NaN));//falseconsole.log('1/0',isFinite(1/0));//falseconsole.log('isNaN',Number.isNaN(15));// falseconsole.log('isNaN',Number.isNaN(NaN));// true}

3.Number.isInteger

Number.isInteger用來(lái)判斷一個(gè)數(shù)是不是整數(shù)

{console.log('13',Number.isInteger(13));// trueconsole.log('13.0',Number.isInteger(13.0));// true console.log('13.1',Number.isInteger(13.1));//falseconsole.log('13',Number.isInteger('13'));// false}

4.Number.MAX_SAFE_INTEGER,Number.MIN_SFAE_INTEGER和isSafeInterger

Number.MAX_SAFE_INTEGER,Number.MIN_SFAE_INTEGER表示js可以準(zhǔn)確表示的值的范圍吧彪,isSafeInterger用來(lái)判斷這個(gè)值是否在安全范圍內(nèi)。

{console.log(Number.MAX_SAFE_INTEGER,Number.MIN_SFAE_INTEGER);console.log('15',Number.isSafeInteger(15));console.log('9999999999999999999999',Number.isSafeInteger(9999999999999999999999));}

5.Math.trunc和Math.sign

Math.trunc方法用于去除一個(gè)數(shù)的小數(shù)部分丢早,返回整數(shù)部分姨裸。Math.sign方法用來(lái)判斷一個(gè)數(shù)到底是正數(shù)、負(fù)數(shù)怨酝、還是零傀缩。對(duì)于非數(shù)值,會(huì)先將其轉(zhuǎn)換為數(shù)值农猬。

{console.log('4.1',Math.trunc(4.1));//4console.log('4.9',Math.trunc(4.9));//4}{console.log('-5',Math.sign(-5))//-1console.log('5',Math.sign(5))//+1console.log('0',Math.sign(0))//0console.log('50',Math.sign(50))//+1console.log('NaN',Math.sign(NaN))//NaN}

6.cbrt

cbrt用來(lái)計(jì)算一個(gè)數(shù)的開方

{console.log('-1',cbrt(-1));//-1console.log('8',cbrt(8));//2}

六 數(shù)組擴(kuò)展

1. Array.of

Array.of方法用于將一組值赡艰,轉(zhuǎn)換為數(shù)組,這個(gè)方法的主要目的,是彌補(bǔ)數(shù)組構(gòu)造函數(shù)Array()的不足斤葱。因?yàn)閰?shù)個(gè)數(shù)的不同慷垮,會(huì)導(dǎo)致Array()的行為有差異。

{letarr =Array.of(1,2,3,4);console.log('arr=',arr);// arr= [1, 2, 3, 4]letemptyArr =Array.of();console.log(emptyArr);// []//與Array方法對(duì)比Array()// []Array(3)// [, , ,]Array(3,11,8)// [3, 11, 8]}

2.Array.from

Array.from方法用于將兩類對(duì)象轉(zhuǎn)為真正的數(shù)組:類似數(shù)組的對(duì)象和可遍歷的對(duì)象(包括ES6新增的數(shù)據(jù)結(jié)構(gòu)Set和Map)料身。

你好

我好

大家好

{? let p = document.querySelectorAll('p');? let pArr =Array.from(p);? pArr.forEach(function(item){? ? console.log(item.textContent);// 你好 我好 大家好})? console.log(Array.from([1,3,5],function(item){returnitem*2}))// [2,6,10]}

3.Array.fill

fill方法使用給定值衩茸,填充一個(gè)數(shù)組。

{console.log('fill-7',[1,3,'undefined'].fill(7));//[7,7,7]console.log('fill,pos',[1,2,3,4,5,7,8].fill(7,1,4));//[1, 7, 7, 7, 5, 7, 8]? // 后兩個(gè)參數(shù)表示索引的位置}

4.entries(),keys() 和 values()

ES6 提供三個(gè)新的方法——entries()祟牲,keys()和values()——用于遍歷數(shù)組说贝。

{for(letindexof[1,2,3,4].keys()){console.log('index',index);// index 0// index 1// index 2// index 3}for(letvalueof[1,2,3,4].values()){console.log('value',value);// value 1// value 2// value 3// value 4}for(let[index,value]of[1,2,4,5,6].entries()){console.log(index,value);// 0 1// 1 2// 2 4// 3 5// 4 }}

5.Array.copyWithin

截取一定長(zhǎng)度的數(shù)字并且替換在相對(duì)應(yīng)的索引的位置

{? console.log([1,4,9,6,7,2,3].copyWithin(1,3,5));//? [1, 6, 7, 6, 7, 2, 3]? // 截取3-5的位置的數(shù)字议惰,從索引1的位置開始替換console.log([1,4,9,6,7,2,3].copyWithin(1,3,6));//? [1, 6, 7, 2, 7, 2, 3] }

6.findIndex和find

數(shù)組實(shí)例的find方法,用于找出第一個(gè)符合條件的數(shù)組成員言询。它的參數(shù)是一個(gè)回調(diào)函數(shù)傲宜,所有數(shù)組成員依次執(zhí)行該回調(diào)函數(shù)函卒,直到找出第一個(gè)返回值為true的成員,然后返回該成員虱咧。如果沒有符合條件的成員腕巡,則返回undefined绘沉。數(shù)組實(shí)例的findIndex方法的用法與find方法非常類似豺总,返回第一個(gè)符合條件的數(shù)組成員的位置喻喳,如果所有成員都不符合條件沸枯,則返回-1。

{console.log([1,2,3,4,5,6].find(function(item){returnitem >3}));//4console.log([1,2,3,4,5,6].findIndex(function(item){returnitem >3}));// 3}

7.includes

Array.prototype.includes方法返回一個(gè)布爾值绑榴,表示某個(gè)數(shù)組是否包含給定的值翔怎,與字符串的includes方法類似赤套。ES2016 引入了該方法。

{console.log([1,2,NaN].includes(1));// trueconsole.log([1,2,NaN].includes(NaN));// true}

8.擴(kuò)展運(yùn)算符

擴(kuò)展運(yùn)算符(spread)是三個(gè)點(diǎn)(...)宣脉。將一個(gè)數(shù)組轉(zhuǎn)為用逗號(hào)分隔的參數(shù)序列塑猖。

console.log(...[1,2,3])// 1 2 3console.log(1, ...[2,3,4],5)// 1 2 3 4 5[...document.querySelectorAll('div')]// [<div>, <div>, <div>]

七 函數(shù)擴(kuò)展

1.默認(rèn)值

ES6 之前羊苟,不能直接為函數(shù)的參數(shù)指定默認(rèn)值;ES6允許為函數(shù)的參數(shù)設(shè)置默認(rèn)值蜡励,即直接寫在參數(shù)定義的后面阻桅。

{functionfn(x,y='hello'){// 默認(rèn)值后面不能再出現(xiàn)形參console.log(x,y);? ? }? ? fn('word');// word hellofn('word','nihao')// word nihao}{leta ='nihao';functiontest(a,b=a){//1.//let a = 1; 參數(shù)變量是默認(rèn)聲明的鳍刷,所以不能用let或const再次聲明console.log(a,b);? ? }? ? test('word');// word word? test();//undefined undefined}{leta ='nihao';functiontest(x,b=a){//2.console.log(x,b)? ? }? ? test('hello');// hello nihao}

3.rest參數(shù)

ES6 引入rest參數(shù)(形式為...變量名)输瓜,用于獲取函數(shù)的多余參數(shù)尤揣,這樣就不需要使用arguments對(duì)象了北戏。rest參數(shù)搭配的變量是一個(gè)數(shù)組,該變量將多余的參數(shù)放入數(shù)組中旧蛾。

{functionfn(...arg){for(letvofarg){console.log(v);? ? ? ? }? ? }? ? fn(1,2,3,4);//1//2//3//4}{console.log(...[1,2,3,4]);// 1锨天,2病袄,3益缠,4console.log('a',...[1,2,3,4]);// a,1,2,3,4}

4.箭頭函數(shù)

ES6 允許使用“箭頭”(=>)定義函數(shù)幅慌。

{letarr =v=>v*2;console.log(arr(2));varsum =(num1, num2) =>{returnnum1 + num2; }//如果箭頭函數(shù)的代碼塊部分多于一條語(yǔ)句,就要使用大括號(hào)將它們括起來(lái)迄靠,并且使用return語(yǔ)句返回掌挚。}

使用注意點(diǎn)

箭頭函數(shù)有幾個(gè)使用注意點(diǎn)吠式。

(1)函數(shù)體內(nèi)的this對(duì)象特占,就是定義時(shí)所在的對(duì)象云茸,而不是使用時(shí)所在的對(duì)象标捺。

(2)不可以當(dāng)作構(gòu)造函數(shù)亡容,也就是說(shuō)闺兢,不可以使用new命令屋谭,否則會(huì)拋出一個(gè)錯(cuò)誤桐磁。

(3)不可以使用arguments對(duì)象,該對(duì)象在函數(shù)體內(nèi)不存在淮逊。如果要用泄鹏,可以用 rest 參數(shù)代替备籽。

(4)不可以使用yield命令车猬,因此箭頭函數(shù)不能用作 Generator 函數(shù)珠闰。

5.綁定 this

函數(shù)綁定運(yùn)算符是并排的兩個(gè)冒號(hào)(::)伏嗜,雙冒號(hào)左邊是一個(gè)對(duì)象伐厌,右邊是一個(gè)函數(shù)挣轨。該運(yùn)算符會(huì)自動(dòng)將左邊的對(duì)象卷扮,作為上下文環(huán)境(即this對(duì)象)画饥,綁定到右邊的函數(shù)上面抖甘。

foo::bar;// 等同于bar.bind(foo);foo::bar(...arguments);// 等同于bar.apply(foo, arguments);consthasOwnProperty = Object.prototype.hasOwnProperty;functionhasOwn(obj, key){returnobj::hasOwnProperty(key);}

尾調(diào)用(Tail Call)是函數(shù)式編程的一個(gè)重要概念衔彻,本身非常簡(jiǎn)單艰额,一句話就能說(shuō)清楚柄沮,就是指某個(gè)函數(shù)的最后一步是調(diào)用另一個(gè)函數(shù)废岂。

{functionfn1(x){console.log('fn1',x);? ? }functionfn2(x){returnfn1(x);// 對(duì)fn1的調(diào)用必須在最后一步操作}? ? fn2(2);}

八 對(duì)象擴(kuò)展

1.屬性的簡(jiǎn)介表示法

ES6 允許直接寫入變量和函數(shù),作為對(duì)象的屬性和方法详囤。這樣的書寫更加簡(jiǎn)潔藏姐。

{leta =5,b=6;letes5 = {a:a,b:b? ? }letes6 = {? ? ? ? a,? ? ? ? b? ? }console.log(es5,es6)// {a: 5, b: 6}? {a: 5, b: 6}letes5_fn = {// fn:function(){console.log('hello')? ? ? ? }? ? }letes6_fn = {? ? ? ? fn(){console.log('hello')? ? ? ? }? ? }console.log(es5_fn.fn,es6_fn.fn);}

2.動(dòng)態(tài)key值

es6允許屬性的key值是動(dòng)態(tài)的變量

{leta ='b';letes5_obj = {a:'c',b:'c'}letes6_obj = {? ? ? ? [a]:'c'// a是動(dòng)態(tài)的變量羔杨,可以自由賦值}console.log(es5_obj, es6_obj);}

3.Object.is

這個(gè)方法相當(dāng)于es5 中的 ===兜材,來(lái)判斷屬性是否相等

{console.log('is',Object.is('a','a'));// trueconsole.log('is',Object.is([],[]));// false? 數(shù)組對(duì)象擁有不同的地址护姆,}

4.Object.assign

Object.assign方法用于對(duì)象的合并卵皂,將源對(duì)象的所有可枚舉屬性灯变,復(fù)制到目標(biāo)對(duì)象添祸。

{console.log('拷貝',Object.assign({a:1},{b:2}));//淺拷貝lettest = {a:2,b:3}for(let[key,value]ofObject.entries(test)){// 遍歷console.log([key,value]);//[a:2]//[b:3]}}

九 Symbol

1.Symbol簡(jiǎn)單舉例

ES6引入了一種新的原始數(shù)據(jù)類型Symbol刃泌,表示獨(dú)一無(wú)二的值耙替。

{leta1 =Symbol();leta2 =Symbol();console.log(a1===a2)// falseleta3 =Symbol.for('a3');leta4 =Symbol.for('a3');console.log(a3===a4);//true}

2.Symbol的一些API

Symbol.for可以用來(lái)命名具有相同的key值的對(duì)象俗扇。

Object.getOwnPropertySymbols方法返回一個(gè)數(shù)組铜幽,成員是當(dāng)前對(duì)象的所有用作屬性名的 Symbol 值。

Reflect.ownKeys方法可以返回所有類型的鍵名厨诸,包括常規(guī)鍵名和 Symbol 鍵名。

{leta1 =Symbol.for('abc');letobj = {? ? ? ? [a1]:123,abc:234,c:345}console.log(obj);// abc:234// c:345// Symbol(abc):123Object.getOwnPropertySymbols(obj).forEach(function(item){console.log('symbol',item,obj[item]);//symbol Symbol(abc) 123})Reflect.ownKeys(obj).forEach(function(item){console.log(item,obj[item]);//abc 234//c 345//Symbol(abc) 123})}

十 Map和Set數(shù)據(jù)結(jié)構(gòu)

1.set的基本用法

ES6 提供了新的數(shù)據(jù)結(jié)構(gòu) Set颤陶。它類似于數(shù)組滓走,但是成員的值都是唯一的搅方,沒有重復(fù)的值姨涡。Set 本身是一個(gè)構(gòu)造函數(shù)涛漂,用來(lái)生成 Set 數(shù)據(jù)結(jié)構(gòu)匈仗。 Set 結(jié)構(gòu)不會(huì)添加重復(fù)的值

{letlist =newSet();? ? list.add(2);? ? list.add(3);console.log(list.size);//2letarr = [1,2,3,4,5];letlist2 =newSet(arr);console.log(list2.size);//5console.log(list2)//{1, 2, 3, 4, 5}letarr2 = [1,2,3,4,2,1];//這里可以當(dāng)作數(shù)組去重letlist3 =newSet(arr2);console.log(list3)//{1, 2, 3, 4}}

add(value):添加某個(gè)值悠轩,返回Set結(jié)構(gòu)本身火架。

delete(value):刪除某個(gè)值距潘,返回一個(gè)布爾值音比,表示刪除是否成功洞翩。

has(value):返回一個(gè)布爾值骚亿,表示該值是否為Set的成員来屠。

clear():清除所有成員俱笛,沒有返回值迎膜。

{letarr = ['add','delete','clear','has'];letlist =newSet(arr);console.log(list);// {"add", "delete", "clear", "has"}list.delete('add');console.log(list);// {"delete", "clear", "has"}console.log(list.has('clear'));// truelist.clear();console.log(list);//{}//set遍歷方法{letarr = ['add','delete','clear','has'];letlist =newSet(arr);for(letkeyoflist.keys()){console.log('keys',key)//keys add//keys delete//keys clear//keys has}for(letvalueoflist.values()){console.log('values',value)//values add//values delete//values clear//values has}for(let[key,value]oflist.entries()){console.log(key,value);//add add//delete delete//clear clear//has has}? ? ? ? list.forEach(function(item){console.log(item)})// add// delete// clear// has}}

2.WeakSet基本用法

WeakSet結(jié)構(gòu)與Set類似磕仅,也是不重復(fù)的值的集合榕订。但是劫恒,它與 Set有兩個(gè)區(qū)別兼贸。首先溶诞,WeakSet 的成員只能是對(duì)象螺垢,而不能是其他類型的值枉圃。

WeakSet中的對(duì)象都是弱引用孽亲,即垃圾回收機(jī)制不考慮 WeakSet 對(duì)該對(duì)象的引用,也就是說(shuō)栖茉,如果其他對(duì)象都不再引用該對(duì)象吕漂,那么垃圾回收機(jī)制會(huì)自動(dòng)回收該對(duì)象所占用的內(nèi)存惶凝,不考慮該對(duì)象還存在于 WeakSet 之中苍鲜。

WeakSet.prototype.add(value):向 WeakSet 實(shí)例添加一個(gè)新成員官辈。

WeakSet.prototype.delete(value):清除 WeakSet 實(shí)例的指定成員拳亿。

WeakSet.prototype.has(value):返回一個(gè)布爾值肺魁,表示某個(gè)值是否在

{constws =newWeakSet();? ? ws.add(1)// TypeError: Invalid value used in weak setws.add(Symbol())// TypeError: invalid value used in weak setletweakset =newWeakSet()// 沒有clear鹅经,set方法瘾晃,不能遍歷letobj = {}? ? ? weakset.add(obj)// weekset.add(2)? WeakSet必須添加的是對(duì)象蹦误,弱引用? console.log(weakset);}

3.Map的基本用法

ES6 提供了 Map 數(shù)據(jù)結(jié)構(gòu)强胰。它類似于對(duì)象偶洋,也是鍵值對(duì)的集合玄窝,但是“鍵”的范圍不限于字符串,各種類型的值(包括對(duì)象)都可以當(dāng)作鍵吗铐。也就是說(shuō)唬渗,Object結(jié)構(gòu)提供了“字符串—值”的對(duì)應(yīng),Map結(jié)構(gòu)提供了“值—值”的

{constmap =newMap([? ? ? ['name','張三'],? ? ? ['title','Author']? ? ]);? ? map.size// 2map.has('name')// truemap.get('name')// "張三"map.has('title')// truemap.get('title')// "Author"}{letmap =newMap();letarr = ['123'];? ? map.set(arr,'456');console.log(map,map.get(arr))// {["123"] => "456"} "456"}{letmap =newMap([['a',123],['b',456]])console.log(map);//{"a" => 123, "b" => 456}console.log(map.size);//2console.log('123'+map.delete('a'));//trueconsole.log(map)// {"b" => 456}map.clear()console.log(map);//{}}

4.WeakMap的一些API

WeakMap只接受對(duì)象作為鍵名(null除外)撑蒜,不接受其他類型的值作為鍵名座菠。

WeakMap的鍵名所引用的對(duì)象都是弱引用浴滴,即垃圾回收機(jī)制不將該引用考慮在內(nèi)升略。因此品嚣,只要所引用的對(duì)象的其他引用都被清除,垃圾回收機(jī)制就會(huì)釋放該對(duì)象所占用的內(nèi)存额嘿。也就是說(shuō)册养,一旦不再需要球拦,WeakMap里面的鍵名對(duì)象和所對(duì)應(yīng)的鍵值對(duì)會(huì)自動(dòng)消失坎炼,不用手動(dòng)刪除引用檩淋。

WeakMap 與 Map 在 API 上的區(qū)別主要是兩個(gè)蟀悦,一是沒有遍歷操作(即沒有key()日戈、values()和entries()方法)浙炼,也沒有size屬性弯屈。因?yàn)闆]有辦法列出所有鍵名钮糖,某個(gè)鍵名是否存在完全不可預(yù)測(cè)店归,跟垃圾回收機(jī)制是否運(yùn)行相關(guān)消痛。這一刻可以取到鍵名秩伞,下一刻垃圾回收機(jī)制突然運(yùn)行了纱新,這個(gè)鍵名就沒了脸爱,為了防止出現(xiàn)不確定性空入,就統(tǒng)一規(guī)定不能取到鍵名歪赢。二是無(wú)法清空轨淌,即不支持clear方法迂烁。因此,WeakMap只有四個(gè)方法可用:get()递鹉、set()盟步、has()、delete()躏结。

{letweakmap =newWeakMap()//沒有clear却盘,set方法媳拴,不能遍歷leto = {}? ? weakmap.set(o,123);console.log(weakmap.get(o));}

十一 proxy和reflect

1.Proxy

Proxy用于修改某些操作的默認(rèn)行為黄橘,等同于在語(yǔ)言層面做出修改,所以屬于一種“元編程”(meta programming)屈溉,即對(duì)編程語(yǔ)言進(jìn)行編程塞关。Proxy 可以理解成,在目標(biāo)對(duì)象之前架設(shè)一層“攔截”子巾,外界對(duì)該對(duì)象的訪問帆赢,都必須先通過(guò)這層攔截,因此提供了一種機(jī)制线梗,可以對(duì)外界的訪問進(jìn)行過(guò)濾和改寫椰于。Proxy這個(gè)詞的原意是代理,用在這里表示由它來(lái)“代理”某些操作仪搔,可以譯為“代理器”瘾婿。

{letobj = {name:'gao',time:'2017-08-13',emp:'123',? }lettemp =newProxy(obj,{? ? get(target,key){returntarget[key].replace('2017','2018');? ? },? ? set(target,key,value){if(key ==='name'){returntarget[key] = value;? ? ? }else{returntarget[key];? ? ? }? ? },? ? has(target,key){if(key ==='name'){returntarget[key];? ? ? }else{returnfalse;? ? ? }? ? },? ? deleteProperty(target,key){if(key.indexOf('i') >-1){deletetarget[key];returntrue;? ? ? }else{returntarget[key];? ? ? }? ? },? ? ownKeys(target){returnObject.keys(target).filter(item=>item!='name');? ? }? })console.log('get',temp.time);//get 2018-08-13temp.time ='2018';console.log('set',temp.name,temp);//set gao? {name: "gao", time: "2017-08-13", temp: "123"}temp.name ='he';console.log('set',temp.name,temp);// set he? {name: "he", time: "2017-08-13", temp: "123"}console.log('has','name'intemp,'time'intemp);//has true falsedeletetemp.time;console.log('delete',temp);//delete? {name: "he", temp: "123"}console.log('ownkeys',Object.keys(temp));//["emp"]}

2.Reflect

Reflect對(duì)象與Proxy對(duì)象一樣,也是 ES6 為了操作對(duì)象而提供的新 API烤咧。Reflect對(duì)象的設(shè)計(jì)目的有這樣幾個(gè)偏陪。

(1) 將Object對(duì)象的一些明顯屬于語(yǔ)言內(nèi)部的方法(比如Object.defineProperty),放到Reflect對(duì)象上≈笙樱現(xiàn)階段笛谦,某些方法同時(shí)在Object和Reflect對(duì)象上部署,未來(lái)的新方法將只部署在Reflect對(duì)象上立膛。也就是說(shuō)揪罕,從Reflect對(duì)象上可以拿到語(yǔ)言內(nèi)部的方法梯码。

(2) 修改某些Object方法的返回結(jié)果,讓其變得更合理好啰。比如轩娶,Object.defineProperty(obj, name, desc)在無(wú)法定義屬性時(shí),會(huì)拋出一個(gè)錯(cuò)誤框往,而Reflect.defineProperty(obj, name, desc)則會(huì)返回false鳄抒。

(3) 讓Object操作都變成函數(shù)行為。某些Object操作是命令式椰弊,比如name in obj和delete obj[name]许溅,而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)讓它們變成了函數(shù)行為。

(4)Reflect對(duì)象的方法與Proxy對(duì)象的方法一一對(duì)應(yīng)秉版,只要是Proxy對(duì)象的方法贤重,就能在Reflect對(duì)象上找到對(duì)應(yīng)的方法。這就讓Proxy對(duì)象可以方便地調(diào)用對(duì)應(yīng)的Reflect方法清焕,完成默認(rèn)行為并蝗,作為修改行為的基礎(chǔ)。也就是說(shuō)秸妥,不管Proxy怎么修改默認(rèn)行為滚停,你總可以在Reflect上獲取默認(rèn)行為。

{letobj = {name:'gao',time:'2017-08-13',emp:'123',? }console.log('reflect get',Reflect.get(obj,'name'));// reflect get gaoReflect.set(obj,'name','hexaiofei');console.log(obj);// {name: "hexaiofei", time: "2017-08-13", emp: "123"}console.log('reflect has',Reflect.has(obj,'name'));//reflect has true}

3.簡(jiǎn)單應(yīng)用

{functionvalidator(target,validator){returnnewProxy(target,{_validator:validator,? ? ? set(target,key,value,proxy){if(target.hasOwnProperty(key)){letva =this._validator[key];if(!!va(value)){returnReflect.set(target,key,value,proxy);? ? ? ? ? }else{throwError(`不能設(shè)置${key}到${value}`);? ? ? ? ? }? ? ? ? }else{throwError(`${key}不存在`);? ? ? ? }? ? ? }? ? })? }constpersonValidators={? ? name(value){returntypeofvalue ==='string'},? ? age(value){returntypeofvalue ==='number'&& value >18;? ? }? }classPerson{constructor(name,age) {this.name = name;this.age = age;returnvalidator(this,personValidators)? ? }? }constperson =newPerson('lilei',30);console.log(person);? person.name =48;}

十二 Class的基本語(yǔ)法

1.簡(jiǎn)介

ES6 提供了更接近傳統(tǒng)語(yǔ)言的寫法粥惧,引入了Class(類)這個(gè)概念键畴,作為對(duì)象的模板。通過(guò)class關(guān)鍵字突雪,可以定義類起惕。基本上挂签,ES6的class可以看作只是一個(gè)語(yǔ)法糖疤祭,它的絕大部分功能盼产,ES5 都可以做到饵婆,新的class寫法只是讓對(duì)象原型的寫法更加清晰、更像面向?qū)ο缶幊痰恼Z(yǔ)法而已戏售。

{classParent{constructor(name='gao') {this.name = name;? ? }? }letv_parent =newParent();console.log(v_parent);//{name: "gao"}}

2.繼承

Class可以通過(guò)extends關(guān)鍵字實(shí)現(xiàn)繼承侨核,這比ES5的通過(guò)修改原型鏈實(shí)現(xiàn)繼承,要清晰和方便很多灌灾。

{classParent{constructor(name='gao') {this.name = name;? ? }? }classchildextendsParent{? }letv_child =newchild();console.log(v_child);//{name: "gao"}}

3.constructor

constructor方法是類的默認(rèn)方法搓译,通過(guò)new命令生成對(duì)象實(shí)例時(shí),自動(dòng)調(diào)用該方法锋喜。一個(gè)類必須有constructor方法些己,如果沒有顯式定義豌鸡,一個(gè)空的constructor方法會(huì)被默認(rèn)添加。

4.super關(guān)鍵字

super這個(gè)關(guān)鍵字段标,既可以當(dāng)作函數(shù)使用涯冠,也可以當(dāng)作對(duì)象使用。在這兩種情況下逼庞,它的用法完全不同蛇更。第一種情況,super作為函數(shù)調(diào)用時(shí)赛糟,代表父類的構(gòu)造函數(shù)派任。ES6 要求,子類的構(gòu)造函數(shù)必須執(zhí)行一次super函數(shù)璧南。第二種情況掌逛,super作為對(duì)象時(shí),在普通方法中司倚,指向父類的原型對(duì)象颤诀;在靜態(tài)方法中,指向父類对湃。super()在子類constructor構(gòu)造方法中是為了獲取this上下文環(huán)境,所以如果在constructor中使用到this,必須在使用this之前調(diào)用super(),反之不在constructor中使用this則不必調(diào)用super()

{classParent{constructor(name='gao') {this.name = name;? ? }? }classchildextendsParent{constructor(name='child'){super(name);this.type ='child'}? ? ? }letv_child =newchild();console.log(v_child);//{name: "child", type: "child"}}

5.getter和setter

與 ES5 一樣崖叫,在“類”的內(nèi)部可以使用get和set關(guān)鍵字,對(duì)某個(gè)屬性設(shè)置存值函數(shù)和取值函數(shù)拍柒,攔截該屬性的存取行為心傀。

{classParent{constructor(name='gao') {this.name = name;? ? }? ? get longName(){return'mk'+this.name;? ? }? ? set longName(value){// console.log(value);this.name = value;? ? }? }letv_parent =newParent();console.log('get',v_parent.longName);//get mkgaov_parent.longName ='hello';console.log('get',v_parent.longName);//get mkhello}

6.靜態(tài)方法

類相當(dāng)于實(shí)例的原型,所有在類中定義的方法拆讯,都會(huì)被實(shí)例繼承脂男。如果在一個(gè)方法前,加上static關(guān)鍵字种呐,就表示該方法不會(huì)被實(shí)例繼承宰翅,而是直接通過(guò)類來(lái)調(diào)用,這就稱為“靜態(tài)方法”爽室。

{classParent{constructor(name='gao') {this.name = name;? ? }statictell(){console.log('tell');? ? }? }letv_parent =newParent();console.log(v_parent);//{name: "gao"}Parent.tell();// tell}

7.靜態(tài)屬性

靜態(tài)屬性指的是Class本身的屬性汁讼,即Class.propName,而不是定義在實(shí)例對(duì)象(this)上的屬性阔墩。

{classParent{constructor(name='gao') {this.name = name;? ? }? ? ? }? Parent.tell ='nihao';letv_parent =newParent();console.log(v_parent);//{name: "gao"}console.log(Parent.tell);// nihao}

十三 Promise

Promise 是異步編程的一種解決方案嘿架,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大。它由社區(qū)最早提出和實(shí)現(xiàn)啸箫,ES6 將其寫進(jìn)了語(yǔ)言標(biāo)準(zhǔn)耸彪,統(tǒng)一了用法,原生提供了Promise對(duì)象忘苛。所謂Promise蝉娜,簡(jiǎn)單說(shuō)就是一個(gè)容器唱较,里面保存著某個(gè)未來(lái)才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果。從語(yǔ)法上說(shuō)召川,Promise 是一個(gè)對(duì)象绊汹,從它可以獲取異步操作的消息。Promise 提供統(tǒng)一的 API扮宠,各種異步操作都可以用同樣的方法進(jìn)行處理西乖。

Promise對(duì)象有以下兩個(gè)特點(diǎn)。

(1)對(duì)象的狀態(tài)不受外界影響坛增。Promise對(duì)象代表一個(gè)異步操作获雕,有三種狀態(tài):Pending(進(jìn)行中)、Fulfilled(已成功)和Rejected(已失斒盏贰)届案。只有異步操作的結(jié)果,可以決定當(dāng)前是哪一種狀態(tài)罢艾,任何其他操作都無(wú)法改變這個(gè)狀態(tài)楣颠。這也是Promise這個(gè)名字的由來(lái),它的英語(yǔ)意思就是“承諾”咐蚯,表示其他手段無(wú)法改變童漩。

(2)一旦狀態(tài)改變,就不會(huì)再變春锋,任何時(shí)候都可以得到這個(gè)結(jié)果矫膨。Promise對(duì)象的狀態(tài)改變,只有兩種可能:從Pending變?yōu)镕ulfiled和從Pending變?yōu)镽ejected期奔。只要這兩種情況發(fā)生侧馅,狀態(tài)就凝固了,不會(huì)再變了呐萌,會(huì)一直保持這個(gè)結(jié)果馁痴,這時(shí)就稱為 Resolved(已定型)。如果改變已經(jīng)發(fā)生了肺孤,你再對(duì)Promise對(duì)象添加回調(diào)函數(shù)罗晕,也會(huì)立即得到這個(gè)結(jié)果。這與事件(Event)完全不同渠旁,事件的特點(diǎn)是攀例,如果你錯(cuò)過(guò)了它船逮,再去監(jiān)聽顾腊,是得不到結(jié)果的。

注意挖胃,為了行文方便杂靶,本章后面的Resolved統(tǒng)一只指Fulfilled狀態(tài)梆惯,不包含Rejected狀態(tài)。

有了Promise對(duì)象吗垮,就可以將異步操作以同步操作的流程表達(dá)出來(lái)垛吗,避免了層層嵌套的回調(diào)函數(shù)。此外烁登,Promise對(duì)象提供統(tǒng)一的接口怯屉,使得控制異步操作更加容易。

Promise也有一些缺點(diǎn)饵沧。首先锨络,無(wú)法取消Promise,一旦新建它就會(huì)立即執(zhí)行狼牺,無(wú)法中途取消羡儿。其次,如果不設(shè)置回調(diào)函數(shù)是钥,Promise內(nèi)部拋出的錯(cuò)誤掠归,不會(huì)反應(yīng)到外部。第三悄泥,當(dāng)處于Pending狀態(tài)時(shí)虏冻,無(wú)法得知目前進(jìn)展到哪一個(gè)階段(剛剛開始還是即將完成)。

如果某些事件不斷地反復(fù)發(fā)生弹囚,一般來(lái)說(shuō)兄旬,使用 Stream 模式是比部署Promise更好的選擇。

1.基本用法

Promise構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù)余寥,該函數(shù)的兩個(gè)參數(shù)分別是resolve和reject领铐。它們是兩個(gè)函數(shù),由 JavaScript 引擎提供宋舷,不用自己部署绪撵。

resolve函數(shù)的作用是,將Promise對(duì)象的狀態(tài)從“未完成”變?yōu)椤俺晒Α保磸?Pending 變?yōu)?Resolved)祝蝠,在異步操作成功時(shí)調(diào)用音诈,并將異步操作的結(jié)果,作為參數(shù)傳遞出去绎狭;reject函數(shù)的作用是细溅,將Promise對(duì)象的狀態(tài)從“未完成”變?yōu)椤笆 保磸?Pending 變?yōu)?Rejected),在異步操作失敗時(shí)調(diào)用儡嘶,并將異步操作報(bào)出的錯(cuò)誤喇聊,作為參數(shù)傳遞出去。

Promise實(shí)例生成以后蹦狂,可以用then方法分別指定Resolved狀態(tài)和Rejected狀態(tài)的回調(diào)函數(shù)誓篱。

// ES5的回調(diào)函數(shù){letajax =function(callback){console.log('nihao');? ? setTimeout(function(){? ? ? callback && callback.call()? ? },1000)? }? ajax(function(){console.log('timeout1');? })}// es6 Promise的用法{letajax =function(){console.log('wohao');returnnewPromise((resolve, reject) =>{? ? ? setTimeout(function(){? ? ? ? resolve();? ? ? },1000);? ? });? }? ajax().then(function(){console.log('promise','timeout1');? })}promise.then(function(value){// promise的用法// success},function(error){// failure});

2.Promise.prototype.then()

Promise實(shí)例具有then方法朋贬,也就是說(shuō),then方法是定義在原型對(duì)象Promise.prototype上的窜骄。它的作用是為 Promise 實(shí)例添加狀態(tài)改變時(shí)的回調(diào)函數(shù)锦募。前面說(shuō)過(guò),then方法的第一個(gè)參數(shù)是Resolved狀態(tài)的回調(diào)函數(shù)邻遏,第二個(gè)參數(shù)(可選)是Rejected狀態(tài)的回調(diào)函數(shù)糠亩。

then方法返回的是一個(gè)新的Promise實(shí)例(注意,不是原來(lái)那個(gè)Promise實(shí)例)准验。因此可以采用鏈?zhǔn)綄懛ㄏ鹘猓磘hen方法后面再調(diào)用另一個(gè)then方法。

{letajax =function(){console.log('dajiahao');returnnewPromise((resolve, reject) =>{? ? ? setTimeout(function(){? ? ? ? resolve();? ? ? },1000);? ? });? };? ajax().then(function(){returnnewPromise((resolve, reject) =>{? ? ? setTimeout(function(){? ? ? ? resolve();? ? ? },2000)? ? });? })? .then(function(){console.log('timeout3');? })}

3.Promise.prototype.catch()

Promise.prototype.catch方法是.then(null, rejection)的別名沟娱,用于指定發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)氛驮。

{letajax =function(num){console.log('dajiahao');returnnewPromise((resolve, reject) =>{if(num>6){console.log('6');? ? ? }else{thrownewError('出錯(cuò)了');? ? ? }? ? });? };? ajax(3).then(function(){console.log('3');? })? .catch(error=>{console.log(error)//出錯(cuò)了})}

4.Promise.all

Promise.all方法用于將多個(gè) Promise 實(shí)例,包裝成一個(gè)新的 Promise 實(shí)例济似。

varp =Promise.all([p1, p2, p3]);

上面代碼中矫废,Promise.all方法接受一個(gè)數(shù)組作為參數(shù),p1砰蠢、p2蓖扑、p3都是 Promise 實(shí)例,如果不是台舱,就會(huì)先調(diào)用下面講到的Promise.resolve方法挽拂,將參數(shù)轉(zhuǎn)為 Promise 實(shí)例桃序,再進(jìn)一步處理。(Promise.all方法的參數(shù)可以不是數(shù)組,但必須具有 Iterator 接口峻汉,且返回的每個(gè)成員都是 Promise 實(shí)例节仿。)

p的狀態(tài)由p1确封、p2键袱、p3決定,分成兩種情況浑厚。

(1)只有p1股耽、p2、p3的狀態(tài)都變成fulfilled钳幅,p的狀態(tài)才會(huì)變成fulfilled物蝙,此時(shí)p1、p2敢艰、p3的返回值組成一個(gè)數(shù)組诬乞,傳遞給p的回調(diào)函數(shù)。

(2)只要p1、p2丽惭、p3之中有一個(gè)被rejected击奶,p的狀態(tài)就變成rejected辈双,此時(shí)第一個(gè)被reject的實(shí)例的返回值责掏,會(huì)傳遞給p的回調(diào)函數(shù)。

{functionloadImg(src){returnnewPromise((resolve, reject) =>{letimg =document.createElement('img');? ? ? img.src=src;? ? ? img.onload =function(){? ? ? ? resolve(img);? ? ? }? ? ? img.onerror =function(error){? ? ? ? reject(error);? ? ? ? }? ? });? }functionshowImgs(imgs){? ? imgs.forEach(function(img){document.body.appendChild(img);? ? })? }Promise.all([? ? loadImg(''),? ? loadImg(''),? ? loadImg(''),? ]).then(showImgs)}

4.Promise.race

Promise.race方法同樣是將多個(gè)Promise實(shí)例湃望,包裝成一個(gè)新的Promise實(shí)例换衬。

varp =Promise.race([p1, p2, p3]);

上面代碼中,只要p1证芭、p2瞳浦、p3之中有一個(gè)實(shí)例率先改變狀態(tài),p的狀態(tài)就跟著改變废士。那個(gè)率先改變的 Promise 實(shí)例的返回值叫潦,就傳遞給p的回調(diào)函數(shù)。

Promise.race方法的參數(shù)與Promise.all方法一樣官硝,如果不是 Promise 實(shí)例矗蕊,就會(huì)先調(diào)用下面講到的Promise.resolve方法,將參數(shù)轉(zhuǎn)為 Promise 實(shí)例氢架,再進(jìn)一步處理傻咖。

下面是一個(gè)例子,如果指定時(shí)間內(nèi)沒有獲得結(jié)果岖研,就將Promise的狀態(tài)變?yōu)閞eject卿操,否則變?yōu)閞esolve。

{functionloadImg(src){returnnewPromise((resolve, reject) =>{letimg =document.createElement('img');? ? ? img.src=src;? ? ? img.onload =function(){? ? ? ? resolve(img);? ? ? }? ? ? img.onerror =function(error){? ? ? ? reject(error);? ? ? ? }? ? });? }functionshowImg(img){letimg =document.createElement('p');? ? p.appendChild(img);document.body.appendChild(p);? }Promise.race([? ? loadImg(''),? ? loadImg(''),? ? loadImg(''),? ]).then(showImgs)}

十四 Iterator 和 for...of 循環(huán)

Iterator 接口的目的孙援,就是為所有數(shù)據(jù)結(jié)構(gòu)害淤,提供了一種統(tǒng)一的訪問機(jī)制,即for...of循環(huán)拓售。當(dāng)使用for...of循環(huán)遍歷某種數(shù)據(jù)結(jié)構(gòu)時(shí)筝家,該循環(huán)會(huì)自動(dòng)去尋找 Iterator 接口。一種數(shù)據(jù)結(jié)構(gòu)只要部署了 Iterator 接口邻辉,我們就稱這種數(shù)據(jù)結(jié)構(gòu)是”可遍歷的“(iterable)溪王。

ES6 規(guī)定,默認(rèn)的 Iterator 接口部署在數(shù)據(jù)結(jié)構(gòu)的Symbol.iterator屬性值骇,或者說(shuō)莹菱,一個(gè)數(shù)據(jù)結(jié)構(gòu)只要具有Symbol.iterator屬性,就可以認(rèn)為是“可遍歷的”(iterable)吱瘩。Symbol.iterator屬性本身是一個(gè)函數(shù)道伟,就是當(dāng)前數(shù)據(jù)結(jié)構(gòu)默認(rèn)的遍歷器生成函數(shù)。執(zhí)行這個(gè)函數(shù),就會(huì)返回一個(gè)遍歷器蜜徽。至于屬性名Symbol.iterator祝懂,它是一個(gè)表達(dá)式,返回Symbol對(duì)象的iterator屬性拘鞋,這是一個(gè)預(yù)定義好的砚蓬、類型為 Symbol的特殊值,所以要放在方括號(hào)內(nèi)盆色。

1.數(shù)組的Symbol.iterator屬性

變量arr是一個(gè)數(shù)組灰蛙,原生就具有遍歷器接口,部署在arr的Symbol.iterator屬性上面隔躲。所以摩梧,調(diào)用這個(gè)屬性,就得到遍歷器對(duì)象宣旱。

{? let arr = ['hellow','world'];? let map = arr[Symbol.iterator]();? console.log(map.next());//{value:"hellow",done:false}? console.log(map.next());//{value:"world",done:false}? console.log(map.next());//{value:"undefined",done:false}}

2.自定義的Iterator接口

{letobj = {start:[1,3,2],end:[7,8,9],? ? [Symbol.iterator](){letself =this;letindex =0;letarr = self.start.concat(self.end);letlen = arr.length;return{? ? ? ? next(){if(index

十五 Genertor

1.基本概念

Generator 函數(shù)有多種理解角度仅父。從語(yǔ)法上,首先可以把它理解成浑吟,Generator函數(shù)是一個(gè)狀態(tài)機(jī)笙纤,封裝了多個(gè)內(nèi)部狀態(tài)。執(zhí)行 Generator 函數(shù)會(huì)返回一個(gè)遍歷器對(duì)象买置,也就是說(shuō)粪糙,Generator函數(shù)除了狀態(tài)機(jī),還是一個(gè)遍歷器對(duì)象生成函數(shù)忿项。返回的遍歷器對(duì)象蓉冈,可以依次遍歷Generator函數(shù)內(nèi)部的每一個(gè)狀態(tài)。形式上轩触,Generator 函數(shù)是一個(gè)普通函數(shù)寞酿,但是有兩個(gè)特征。一是脱柱,function關(guān)鍵字與函數(shù)名之間有一個(gè)星號(hào)伐弹;二是,函數(shù)體內(nèi)部使用yield表達(dá)式榨为,定義不同的內(nèi)部狀態(tài)(yield在英語(yǔ)里的意思就是“產(chǎn)出”)惨好。

{? let tell = function* (){yield'a';yield'b';return'c';? }? let k = tell();? console.log(k.next());//{value:"a",done:false}? console.log(k.next());//{value:"b",done:false}? console.log(k.next());//{value:"c",done:true}? console.log(k.next());//{value:undefined,done:true}}

2.與 Iterator 接口的關(guān)系

由于 Generator 函數(shù)就是遍歷器生成函數(shù),因此可以把Generator賦值給對(duì)象的Symbol.iterator屬性随闺,從而使得該對(duì)象具有 Iterator 接口日川。

{letobj = {};? obj[Symbol.iterator] =function* (){yield'1';yield'2';yield'3';? }for(letvalueofobj){console.log(value);// 1 2 3}}

3.next方法

{letstate =function* (){yield'a';yield'b';yield'c';? }letstatus = state();console.log(status.next());//aconsole.log(status.next());//bconsole.log(status.next());//cconsole.log(status.next());//aconsole.log(status.next());//bconsole.log(status.next());//cconsole.log(status.next());//a}

4.Genertor的簡(jiǎn)單應(yīng)用

//簡(jiǎn)單的抽獎(jiǎng){letdraw =function(count){console.info(`剩余${count}次`);? }letchou =function*(count){while(count>0) {? ? ? count--;yielddraw(count);? ? }? }letstart = chou(5);letbtn =document.createElement('button');? btn.id ='start';? btn.textContent ='抽獎(jiǎng)';document.body.appendChild(btn);document.getElementById('start').addEventListener('click',function(){? ? start.next();? },false);}// 長(zhǎng)輪詢{letajax =function* (){yieldnewPromise((resolve, reject) =>{? ? ? setTimeout(function(){? ? ? ? resolve({code:1})? ? ? },200)? ? });? }letpull =function(){letgenerator = ajax();letstep = generator.next();? ? step.value.then(function(d){if(d.code !=0){? ? ? ? setTimeout(function(){console.log('wait');//隔一秒輸出 waitpull();? ? ? ? },1000)? ? ? }else{console.log(d);? ? ? }? ? })? }? pull();}

十六修飾器

1.方法的修飾

修飾器函數(shù)一共可以接受三個(gè)參數(shù),第一個(gè)參數(shù)是所要修飾的目標(biāo)對(duì)象矩乐,即類的實(shí)例(這不同于類的修飾龄句,那種情況時(shí)target參數(shù)指的是類本身)回论;第二個(gè)參數(shù)是所要修飾的屬性名,第三個(gè)參數(shù)是該屬性的描述對(duì)象分歇。

{letreadonly =function(target,name,descriptor){? ? descriptor.writable =false;returndescriptor;? };classtest{? ? @readonly? ? time(){return'2017-08-27'}? }lettests =newtest();console.log(tests.time());// 2017-08-27// let testss = new test();// // tests.time = function(){// //? console.log('2017-08-28');// // }// console.log(tests.time());? //Cannot assign to read only property 'time' of object}

2.類的修飾

修飾器是一個(gè)對(duì)類進(jìn)行處理的函數(shù)傀蓉。修飾器函數(shù)的第一個(gè)參數(shù),就是所要修飾的目標(biāo)類职抡。

{lettypename =function(target,name,descriptor){? ? target.myname ='hello';? };? @typenameclasstest{? }console.log(test.myname)// hello}

十七模塊化

ES6 模塊不是對(duì)象葬燎,而是通過(guò)export命令顯式指定輸出的代碼,再通過(guò)import命令輸入繁调。

{exportletA =123;exportfunctiontext(){console.log('123');? }exportclasshello{? ? text(){console.log('345');? ? }? }}{letA =123;functiontext(){console.log('123');? }classhello{? ? text(){console.log('345');? ? }? }exportdefault{? ? A,? ? text,? ? hello? }}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末萨蚕,一起剝皮案震驚了整個(gè)濱河市靶草,隨后出現(xiàn)的幾起案子蹄胰,更是在濱河造成了極大的恐慌,老刑警劉巖奕翔,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件裕寨,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡派继,警方通過(guò)查閱死者的電腦和手機(jī)宾袜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)驾窟,“玉大人庆猫,你說(shuō)我怎么就攤上這事∩鹇纾” “怎么了月培?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)恩急。 經(jīng)常有香客問我杉畜,道長(zhǎng),這世上最難降的妖魔是什么衷恭? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任此叠,我火速辦了婚禮,結(jié)果婚禮上随珠,老公的妹妹穿的比我還像新娘灭袁。我一直安慰自己,他們只是感情好窗看,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布茸歧。 她就那樣靜靜地躺著,像睡著了一般烤芦。 火紅的嫁衣襯著肌膚如雪举娩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音铜涉,去河邊找鬼智玻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛芙代,可吹牛的內(nèi)容都是我干的吊奢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼纹烹,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼页滚!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起铺呵,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤裹驰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后片挂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體幻林,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年音念,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了沪饺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡闷愤,死狀恐怖整葡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情讥脐,我是刑警寧澤遭居,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站攘烛,受9級(jí)特大地震影響魏滚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜坟漱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一鼠次、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧芋齿,春花似錦腥寇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至栅炒,卻和暖如春掂摔,著一層夾襖步出監(jiān)牢的瞬間术羔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工乙漓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留级历,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓叭披,卻偏偏與公主長(zhǎng)得像寥殖,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子涩蜘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

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