ES6學(xué)習(xí)筆記

什么是ES6倒慧?

? ? ECMAScript 6.0 是繼ECMAScript 5.1 之后 JavaScript 語言的下一代標(biāo)準(zhǔn)摆出,發(fā)布在2015年6月掖举,它的目標(biāo)快骗,是使得JavaScript?語言可以用來編寫復(fù)雜的大型應(yīng)用程序,成為企業(yè)級開發(fā)語言塔次。

一方篮、let、const命令

let励负、const與var的區(qū)別藕溅?

a. let、const有塊級作用域的概念继榆,只要是定義的變量巾表,就是一個塊級作用域汁掠;var只有在函數(shù)中才有作用域;

b. let集币、const不允許重復(fù)聲明考阱;

c. let和var聲明的變量,都可以再修改鞠苟,而const定義的是常量乞榨,值是不可以修改的(對象除外,對象的屬性可以修改)

作用域的概念:

ES5有兩個作用域:全局和局部

ES6有了塊作用域的概念:塊作用域偶妖,通俗的理解姜凄,就是一個大括號,就是一個塊作用域趾访;

let聲明

案例:

使用let聲明的變量不可重復(fù)态秧,如下

????function test2(){

? ????? let a = 1;

? ????? let a = 2;

????}

????test2()

這樣聲明會報下圖錯誤:

google報錯
控制臺報錯

這個意思是,a變量重復(fù)聲明了扼鞋;

const聲明

const定義時申鱼,必須要給初始值,否則下面再重新賦值會報錯云头,因為const定義的值不可以修改捐友;

const聲明的是常量,不可以修改(一般的值是不可以修改的昏滴,如果是對象格式是可以修改的谣殊,比如給已創(chuàng)建的對象中添加屬性是可以的)拂共,并且聲明時必須要賦值宜狐;

用途:為了防止意外修改變量,比如柑爸,引入庫名祥诽,組件名等

二厘熟、解構(gòu)賦值

什么是解構(gòu)賦值绳姨?

es6入門中的解釋:ES6 允許按照一定模式购撼,從數(shù)組和對象中提取值迂求,對變量進(jìn)行賦值毫玖,這被稱為解構(gòu);?

模式匹配:

?左邊和右邊要的數(shù)據(jù)格式要一樣十气;

解構(gòu)賦值的分類

這里重點理解:數(shù)組解構(gòu)與對象解構(gòu)

如果解構(gòu)賦值沒有找到對應(yīng)的賦值叶眉,這時默認(rèn)是undefined

數(shù)組解構(gòu)賦值:

常規(guī)寫法

使用場景

對象解構(gòu)賦值

在對象中的解構(gòu)賦值與數(shù)據(jù)的順序是無關(guān)的饱溢,比如:

let {a,b,c} = {b:10,a=11,c=12}

console.log(a); // 11?

json賦值重點掌握

上面的json格式解構(gòu)賦值時潘鲫,key名要與data數(shù)據(jù)中的key名一致状植;否則找不到對應(yīng)的數(shù)據(jù)振定,會顯示undefined;

解構(gòu)賦值給默認(rèn)值

語法:

let {time:12,id=0} = {}

用途:

比如在寫運動框架時,需要對傳過來的參數(shù)加默認(rèn)值;

ES5寫法:

function move(obj,json,options){

? ? options = options || {};

? ? options.time = options.time || 300;?

}

ES6解構(gòu)賦值寫法:

function move(obj,josn,{time=300}={}){

}

三、正則擴(kuò)展

新增的特性

ES5與ES6寫法對比

ES6增加U和Y的修飾符

U 修飾符

四瘤旨、字符擴(kuò)展

字符串新增特性

字符串中新增了幾個方法,是es7預(yù)案的,需要下載補丁才會支持贺辰,否則會報錯,所以在當(dāng)前項目下,安裝babel-polyfill庫,如圖:

安裝成功后,需要在index.js入口文件引入這個庫歹鱼,就可以進(jìn)行使用了掺涛,如圖:

a).字符Unicode表示法

b).codPointAt()使用方法

c).includes(str)、startsWith(str)、endsWith(str)方法的使用

d).repeat(number)方法的使用

e).模版字符串

f).padStart(s1,s2)拧粪、padEnd(s1,s2)方法濒析,ES7提案的API,很重要!U肿ぁ骏啰!

j).標(biāo)簽?zāi)0?/h4>

String.raw

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

數(shù)值處理新增特性:

????1.新增方法 壁熄;2.方法調(diào)整

二進(jìn)制與八進(jìn)制

Number.isFinite()

Number.isInteger()

Number.isSafeInteger()方仿、Number.MAX_SAFE_INTEGER此洲、Number.MIN_SAFE_INTEGER

Math.trunc()

Math.sign()

Math.cbrt()

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

ES5方法回顧:

1.遍歷數(shù)組的方法

說明:通過遍歷數(shù)組可以得到下標(biāo)和下標(biāo)對應(yīng)的值汁汗;

forEach()斤程、map()扁藕、filter()、every()、some()

forEach()使用方法

let arr =[1,3,4,5,6,7]

let newArr = arr.forEach(function(item,index){

? ? //可以得到值和下標(biāo)

? ? console.log(item,index)

});

console.log(newArr) // undefined

forEach的返回值為 undefined

map()使用方法

let arr =[1,3,4]

let newArr = arr.map(function(item,index){

? ?? //可以得到值和下標(biāo)? ?

? ? ?console.log(item,index)

});

console.log(newArr) // undefined

map的返回值為[ undefined , undefined , undefined]

map會把返回的值放到一個新的數(shù)組中,默認(rèn)return 是undefined瞬痘,所以上面數(shù)組有幾項察绷,就返回幾個undefined喘沿。

所以通過這一點,就可以把循環(huán)得到的值念赶,進(jìn)行計算翰灾,通過return 再返回到新數(shù)組中致开;

具體實例如下:

let arr =[1,3,4]

let newArr = arr.map(function(item,index){? ???

//將循環(huán)的每一項乘以2后糜芳,再返回到新數(shù)組中

? return item * 2;

});

console.log(newArr);//[2,6,8] 得到的是計算后的新數(shù)組

filter()使用方法

filter也可以循環(huán)數(shù)組,得到下標(biāo)和值,但是更多作為過濾使用;具體如下:

//過濾出小于3的數(shù)

let arr = [1,2,3,4];

let newArr = arr.filter(function(item,index){

? ? return item < 3;

});

//當(dāng)不寫return 時返回的是一個空數(shù)組

console.log(newArr); // [] ?得到一個空數(shù)組

filter的返回值,返回的是回調(diào)函數(shù)中為true的那一項

如果上案例,return item < 3 ,這時返回的是小于3的數(shù);

ES6新方法:

數(shù)組復(fù)制的方法:

1) for循環(huán);

2) Array.from(arr);//數(shù)組新增from()方法

3) let arr2 = [...arr]质况;//展開運算符

Array.of()

Array.from()

fill()

keys()臼朗、values()誊涯、entries()

copyWithin(s1,s2,s3)

find()取逾、findIndex()

includes(num)

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

ES5中參數(shù)是沒有默認(rèn)值的琉用;

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

ES5的默認(rèn)值

根據(jù)以上es5中默認(rèn)值的情況來看晶丘,如果參數(shù)是0,會被讀成false,導(dǎo)致運算出現(xiàn)問題本股;

所以es6擴(kuò)展了直接給默認(rèn)值的寫法案站,如下:

ES6的默認(rèn)值

關(guān)于函數(shù)作用域

rest參數(shù)(...)

擴(kuò)展運算符(...)

1.數(shù)組的擴(kuò)展:將一個數(shù)組轉(zhuǎn)為逗號分隔的參數(shù)序列炒刁;

說明:是把數(shù)組中的值里伯,以逗號分隔脖镀,把每個值展開强窖;不是轉(zhuǎn)成字符串;

例:找到數(shù)組中的最大值

let arr =[1,5,7,9,3,55];

//原始做法:

console.log(Math.max(1,5,7,9,3,55));//55

//使用擴(kuò)展運算符的做法:

console.log(Math.max(...arr));//55

2.對象的擴(kuò)展:用于取出對象中所有可遍歷的屬性,拷到當(dāng)前對象中;

例:

let obj1 ={a:1,b:2};

let obj2 = {

????...obj1 密末, ?

? ? c:3 ? //這里也可以寫自己的屬性

//obj1 中有a屬性握爷,那么如果obj2中再寫一個a屬于跛璧,就會把obj1中已擴(kuò)展過來的a屬于的值改變

? ? a:66 ?//這樣再打印obj2的a屬性就是66

};?

說明以上這樣的做法,相當(dāng)于淺拷貝追城;

箭頭函數(shù)

注意事項:

????1.箭頭函數(shù)中沒有arguments對象,如果要用燥撞,可以用rest參數(shù)代替座柱;

????2.不能當(dāng)作構(gòu)造函數(shù),不可以使用new命令物舒,否則會拋出錯誤(Fn is not constructor)色洞;

????3.不能當(dāng)作Generator函數(shù)使用;

this指向

es5普通函數(shù)中的this

????1. this表示誰調(diào)用的就是誰冠胯;

????2. 默認(rèn)情況火诸,在嚴(yán)格模式下返回是undefined,非嚴(yán)格模式下是window荠察;

????3. 可以用call,apply,bind改變this的指向置蜀;

es6函數(shù)中的this

????1. 箭頭函數(shù)體內(nèi)沒有自己的this對象,所以在使用的時候悉盆,

? ? ? ? 其內(nèi)部的this就是定義時所在環(huán)境的對象盯荤,而不是使用時所在環(huán)境的對象;

????2. 不可以用call,apply,bind改變this的指向焕盟;

????3. 箭頭函數(shù)中沒有arguments對象秋秤,如果要用,可以用rest參數(shù)代替脚翘;

普通函數(shù)與箭頭函數(shù)this指向示例

尾調(diào)用

八.對象擴(kuò)展

*這里的擴(kuò)展指的Object對象灼卢,不是指類生成的對象

簡潔表示法

屬性表達(dá)式

新增API

Object.is(str1,str2)

判斷兩個字符串是否相等

str1是否與str2相等,這個判斷與es5中的 '===' 判斷是一樣的

console.log(Object.is('a','a'));//true

//數(shù)組也是引用類型堰怨,所以這里是false

console.log(Object.is([],[]));//false

Object.assign(str1,str2):拷貝

str1:要拷貝到這個對象上;

str2:把str2對象拷貝到str1對象上蛇摸;

注意點:

????1. 這種拷貝的屬性是有限制的备图,屬于淺拷貝;

????2. 只拷貝對象自身上的屬性赶袄,如果對象有繼承和不可枚舉的屬性揽涮,是不可以拷貝的;

? ? 3. 靜態(tài)方法饿肺,返回值是str1對象蒋困;

console.log(Object.assign({a:'a'},{b:'b'}));//{a: "a", b: "b"}

Object.entries(obj)

獲取對象的key和value的值,傳入要拷貝的對象

let test ={a:123,b:456};

for(let [key,value] of Object.entries(test)){

????console.log( [key,value] );//["a", 123]? ["b", 456]

}

擴(kuò)展運算符

let arr =[1,2,3,4];

console.log(...arr);//1 2 3 4

//下面這個是ES7提的預(yù)案敬辣,暫時沒有支持方法

let {a,b,...c}={a:'test',b:'kill',c:'ddd',d:'ccc'};//這樣寫頁面會報語法錯誤

Symbol數(shù)據(jù)類型

Symbol的概念:提供獨一無二的值雪标,聲名的值永遠(yuǎn)不會重復(fù)和相等零院;

聲明方法

方法一:這種是直接聲名Symbol值,值一定不會相等村刨;

leta1 =Symbol();

leta2 =Symbol();

console.log(a1===a2);//false

方法二:使用Symbol.for(str)方法聲名告抄;

str:是Symbol中的key值,有這個key值嵌牺,for方法在聲名這個獨一無二的變量時打洼,會先檢查key值是不是在全局注冊過,如果注冊過返回注冊時候的值逆粹,如果沒有注冊過募疮,就會聲成一個獨一無二的值;

這種聲名的好處:參數(shù)中是key名僻弹,相當(dāng)于給Symbol起了個名字阿浓,方便之后的調(diào)用;

let ?a3 = Symbol.for('a3');

let ?a4 = Symbol.for('a3');

true 就表示 a3 和 a4 的值是相等的奢方,因為 a4 的Symbol的key值是已經(jīng)注冊過了搔扁,聲名 a3 時注冊的,

所以 a3 的這個key值蟋字,存在的變量就是 a3,所以兩者比較是true

console.log( a3 === a4 );//true?

Symbol的作用

獲取Symbol的屬性

九.數(shù)據(jù)結(jié)構(gòu)

Set()

定義方法

????1> 通過new方式來創(chuàng)建 new Set()

????2> new Set(arr) 可以向Set中加入一個數(shù)組結(jié)構(gòu)的數(shù)據(jù)稿蹲,會自動變成Set類型的數(shù)據(jù)

Set 中的一些操作方法

????add(str):向Set中添加成員;

????delete(str):刪除Set中str元素鹊奖,返回刪除后的Set集合

????clear():清空所有Set中的元素苛聘,返回清空后的Set集合

????has(str):檢查Set中有沒有str元素,返回boolean忠聚,有true,沒有false

????size屬性:獲取Set的成員數(shù)量(長度)设哗;

Set的特性

Set中的元素是不可以重復(fù)的,如果元素中有重復(fù)两蟀,會只顯示不重復(fù)的元素网梢,重復(fù)元素會自動去掉,利用這個特性可以對數(shù)組進(jìn)行去重赂毯。

let ?arr =[1,1,1,2,2,3,3];

let ?list =newSet(arr);

console.log(list);//{1, 2, 3}

在去重的時候需要注意战虏,Set只去重同數(shù)據(jù)類型的數(shù)據(jù),數(shù)組中不同數(shù)據(jù)類型是不會強(qiáng)制類型轉(zhuǎn)換的党涕;

let ?arr2 =[1,'1',2,2,3,3];

let ?list2 =newSet(arr2);

//通過打印出的元素可以看出沒有類型轉(zhuǎn)換

console.log(list2);// {1, "1", 2, 3}

Set實例的遍歷(讀取里面的元素)

使用keys()烦感、values()、entries()膛堤、forEach手趣、直接使用let of來遍歷里面的元素

WeakSet()

WeakSet與Set的區(qū)別:

????1. 支持的數(shù)據(jù)類型不一樣,WeakSet的元素只能是對象(boolean,String等這些都不可以)肥荔;

????2. WeakSet中的對象是一個弱引用绿渣,不會去檢測這個對象有沒有在其它地方用過朝群, 不會跟GC掛勾,就是說怯晕,在WeakSet中添加了一個對象潜圃, ? ? ? ? ? 這個對象不是值拷過來,只是地址的引用舟茶,而且也不會去檢測這個地址是不是返回GC回收了谭期;

????3. 有些Set的屬性和方法WeakSet是沒有的(clear()、size屬性吧凉、不能遍歷)隧出;

WeakSet方法:

????1. add(val):添加成員

????2. delete(val):刪除成員

????3. has(val):判斷val成員是否存在,返回boolean類型阀捅,true存在胀瞪,反之false

使用案例:

Map()對象

Map的方法:

????1. set(key,value):添加元素,key,value格式的

????2. get(key):根據(jù)key名饲鄙,找對應(yīng)的value值

????3. delete(key):刪除key名對應(yīng)的值

????4. clear():清空map

????5. size屬性:獲取map中的成員數(shù)量

Map的循環(huán):

? ? 不能使用for ..in凄诞,沒有效果;需要使用for ...of來循環(huán)

例如:

let map = new Map();

map.set('a','aaa');

map.set('b','bbb');

for(let key of map){

? ? console.log(key);//a,aaa, ?b,bbb

}

注意:這里of 后面直接寫map 得到的是key和value忍级,因為這里默認(rèn)是map.entries()帆谍;

也可以是只循環(huán)出key 或者 value

寫法如下:

for(let key of map.keys()){ ? //只循環(huán)key

????console.log(key);//a ?b

}

for(let value of map.values()){? ?????//只循環(huán)value

????console.log(value);//aaa ?bbb

}

Map的兩種寫法:

WeakMap()

WeakMap與Map的區(qū)別:

????1. 支持的數(shù)據(jù)類型不一樣,WeakSet的元素只能是對象(boolean,String等這些都不可以)轴咱;

????2. WeakSet中的對象是一個弱引用汛蝙,不會去檢測這個對象有沒有在其它地方用過,不會跟GC掛勾朴肺,就是說窖剑,在WeakSet中添加了一個對象,

? ? ? ? 這個對象不是值拷過來戈稿,只是地址的引用西土,而且也不會去檢測這個地址是不是返回GC回收了;

????3. 有些Set的屬性和方法WeakSet是沒有的(clear()鞍盗、size屬性需了、不能遍歷);

WeakMap的方法:

????1. add(val):添加成員

????2. delete(val):刪除成員

????3. has(val):判斷val成員是否存在橡疼,返回boolean類型援所,true存在庐舟,反之false

let weakMap = new WeakMap();

let o ={};

weakMap.set(0,123);

console.log(weakMap.get(o));//123

數(shù)據(jù)結(jié)構(gòu)對比

說明:在es5中欣除,經(jīng)常使用的數(shù)據(jù)結(jié)構(gòu)就是Array和object來存儲;es6中挪略,新增了Map和Set历帚,那么什么時候使用這些類似滔岳,下面就做一個對比;

數(shù)據(jù)結(jié)構(gòu)橫向?qū)Ρ韧炖危銎酌海椋那莅危瑒h

map和array的對比

增加成員

增加后的信息

查詢成員

修改成員

修改后的信息

刪除成員

set和array的對比

增加成員

增加后的信息

查詢成員

修改成員

修改后的信息

刪除成員

Map,Set與Object對比

增加成員

增加后的信息

查詢成員

修改成員

修改后信息

刪除成員

通過幾上對比刘离,提一個建議性的總結(jié),純屬個人看法:

能使用map睹栖,不使用數(shù)組硫惕,如果對數(shù)據(jù)要求高,數(shù)據(jù)結(jié)構(gòu)要求存儲的唯一性野来,考慮set恼除,放棄使用object;

Proxy與Reflect

Proxy:代理的意思曼氛,作用就是相當(dāng)于代理商豁辉,連接了用戶與對象最中間的那一層;

Reflect:反射Object的作用舀患;

這兩種的方法是一模一樣的徽级,只是生成對象的形式不一樣;這里只演示Proxy的方法构舟;

Proxy是通過new的方式灰追;Reflect是直接調(diào)用,如Reflect.get這樣的寫法狗超;

Proxy對象說明:

原始數(shù)據(jù)對象弹澎,通過Proxy對象,對原始數(shù)據(jù)進(jìn)行了代理努咐,代理后苦蒿,會生成一個新的對象,如下案例monitor渗稍,之后對這個數(shù)據(jù)的操作佩迟,都是對monitor對象進(jìn)行操作,最終Proxy都會將操作后的數(shù)據(jù)竿屹,返回給obj报强。可以理解成拱燃,Proxy對obj所有屬性有一個讀取的作用秉溉,可以說是攔截,也可以是代理;

案例:

let obj ={ //原始數(shù)據(jù)召嘶,可以看做是供應(yīng)商

? ? time:'2017-12-27',

????name:'net',

????_r:123

};

/*

????Proxy(obj,{})

????obj:要代理的數(shù)據(jù)對象父晶;{}:這里面實現(xiàn)這些代理的方法

*/

????let monitor =new Proxy(obj,{

????/*

????????get(target,key):攔截(代理)對象屬性的讀取

????????target:就是obj這個原始數(shù)據(jù)中所有的數(shù)據(jù);

????????key:數(shù)據(jù)對象中的key名弄跌,下面的monitor調(diào)用哪個屬性甲喝,

????????這個key就是哪個屬性名

*/

? ? get(target,key){

????//將讀取到的2017換成2018

? ? ? ? return target[key].replace('2017','2018');

????},

/*

????????set(target,key,value):攔截對象設(shè)置屬性

????????target:原始數(shù)據(jù)對象; key:要修改的屬性铛只;value:要修改的值埠胖;

*/

? ? set(target,key,value){

????//這里舉例只改key值是name的數(shù)據(jù),其它的值不可以修改

? ? ? ? if(key==='name'){//當(dāng)key是name時

????//就讓name的值,等于value

? ? ? ? ? ? return target[key] =value;

????}else{

????????//否則返回之前的值

? ? ? ? ? ? return target[key];

????}

},

/*

????has(target,key):判斷當(dāng)前對象中淳玩,是否有某個屬性

????攔截key in object操作

*/

? ? has(target,key){

????//要只暴露name屬性,就是說通過 key in object方法押袍,

????//只能判斷到name屬性是存在的,其它都查不到

? ? ? ? if(key==='name'){

????????????return target[key];

????????}else{

????????????return false;

????????}

????},

/*

????????deleteProperty(target,key):攔截delete

????????target:原始數(shù)據(jù)對象凯肋;key:數(shù)據(jù)中的key值

*/

? ? deleteProperty(target,key){

????//這里攔截下劃線開頭的屬性谊惭,就可以刪除,其它的全部不可以刪除

? ? ? ? if(key.indexOf('_') >-1){

????????????delete target[key];

? ? ? ? ? ? ?return true

? ? ? ? }else{

????????????return target[key];

????????}

????},

/*

????????ownKeys(target):

????????攔截Object.keys,Object.getOwnPropertySymbols,Object.getOwnPropertyNames侮东,

????????要獲取的屬性名圈盔。保護(hù)指定屬性不被以上這些方法獲取到

*/

? ? ownKeys(target){

????//通過Object.keys把原始key者拿出來,然后再過濾

? ? ? ? return Object.keys(target).filter(item=>item !='time')

? ? }

});

//通過打印可以看出悄雅,Proxy代理了原始數(shù)據(jù)驱敲,并做出修改,這不會影響到原始數(shù)據(jù)宽闲;

????console.log(monitor.time);//2018-12-27

????console.log(obj.time);//2017-12-27

????monitor.time='2019';

????console.log(monitor.time);//2018-12-27? 并沒有修改成2019


????monitor.name='hello';

????console.log(monitor.name);//hello? 這里就改變了众眨,說明代理的set方法起了作用

????console.log('name' in monitor);//true 查詢到有這個屬性

????console.log('time' in monitor);//false 沒查詢到有這個屬性,因為限制了查詢


? ? delete monitor.time;

????console.log(monitor.time);//發(fā)現(xiàn)獲取到了容诬,說明沒有被刪除

????delete monitor._r;

????console.log(monitor);?//{time: "2017-12-27", name: "hello"} 發(fā)現(xiàn)被刪除了娩梨,攔截是有作用的

????console.log(Object.keys(monitor));// ["name", "_r"]? 這里沒有time,time被攔截保持了

總結(jié):通過用戶拿到的對象览徒,和原始對象狈定,之間是不可以直接操作的,要通過代理习蓬,在代理的層面纽什,可以通過不同的業(yè)務(wù)邏輯來做相應(yīng)的處理;比如怎么讀躲叼,怎么寫芦缰;

實際應(yīng)用場景:

通過Proxy和Reflect來實現(xiàn)業(yè)務(wù)解耦的校驗?zāi)K;比較常用的應(yīng)用場景枫慷;

function validator(target,validator){

????return new Proxy(target,{

????????//這里就是進(jìn)入到代理了

? ? ? ? _validator :validator,

????set(target,key,value,proxy){//這里是Proxy對象的set方法

????//判斷當(dāng)前目標(biāo)對象让蕾,有沒有Key值

? ? ? ? ? ? if(target.hasOwnProperty(key)){

? ? ? ? ? ? ? ? ? ? let va =this._validator[key];//把這個條件,這個條件是封裝好的驗證方法包斑,拿出來

????????????if(!!va(value)){//如果這個是存在,就把值拿出來

????????????//這個時候涕俗,就把代理返回到真實數(shù)據(jù)中

? ? ? ? ? ? ? ? ? ? ? ? return Reflect.set(target,key,value,proxy)

? ? ? ? ? ? ? ? ? ? }else{//不存在,就拋出異常

? ? ? ? ? ? ? ? ? ? ? ? throw Error(`不能設(shè)置${key}到${value}`)

? ? ? ? ? ? ? ? ? ? }

????????????????}else{//如果沒有就拋出異常

????????????????????//不存在就把key顯示出去

? ? ? ? ? ? ? ????????? throw Error(`${key} 不存在`)

? ? ? ? ? ????? }

????????}

????????})

}

????const? personValidator = {

????????//name校驗的方法神帅,如果name是string類型再姑,就允許代理修改,否則不允許

? ? ????????name(val){

????????return typeof? val==='string'

? ? },

????//age必須是數(shù)字找御,并且大于18

? ? ????age(val){

????????????return typeof? val ==='number' &&val >18;

????????}

????}

????????//創(chuàng)建一個Person對象

????????class Person{

????????????constructor(name,age){//構(gòu)造函數(shù)

? ? ? ????? this.name =name;

????????????this.age =age;

????????????????//返回的是一個代理

? ? ? ????? return validator(this,personValidator)

? ? ????}

????}

? ? //下面就可以實際驗證了

????const person =new Person('lilei',30);

????console.log(person)

十.類與對象

類的基本定義與對象的生成

類的繼承

繼承傳遞參數(shù)

父類構(gòu)造函數(shù)中的參數(shù)元镀,如何傳遞到子類參數(shù)中,并且子類如何替換繼承過來的父類參數(shù)霎桅;

使用super()來實現(xiàn)子類向父類傳遞參數(shù)栖疑;

????super():不傳參數(shù)時,表示子類全部使用父類的所有默認(rèn)參數(shù)和值滔驶;

????super(str1...):傳參數(shù)時遇革,表示要替換父類的參數(shù),需要替換幾個揭糕,就傳幾個萝快;

關(guān)于super特別要注意:在繼承關(guān)系中,子類在傳遞參數(shù)中著角,使用了super揪漩,那么super一定要放在子類

構(gòu)造函數(shù)中的第一行,否則會報錯吏口;

getter與setter

靜態(tài)方法

靜態(tài)屬性

十一.Promise

什么是promise:實際上就是一個對象奄容,主要是用來傳遞異步操作的數(shù)據(jù);

什么是異步:比如产徊,a和b兩個函數(shù)昂勒,a執(zhí)行完再執(zhí)行b,在程序上舟铜,這個步驟叁怪,有兩種方式去執(zhí)行:

? ? ? ? ? ? ? ? ? ? ? 一種是通過回調(diào),一種是事件觸發(fā)的方式深滚;

promise的作用:解決異步操作的問題奕谭;

es5的異步寫法

ES6的promise寫法

連續(xù)串行的promise執(zhí)行

關(guān)于串行的問題

關(guān)于串行過程,如果在中間某一步出錯了痴荐,怎么捕獲這個錯誤血柳?

使用promise提供的catch來捕獲。

promise兩個重要場景

Promise.all()的使用場景

使用promise.all的方法生兆,把多個promise的實例难捌,當(dāng)做是一個promise實例膝宁;

promise.all([p1,p2,p3]):這里傳的是一個數(shù)組格式,數(shù)組傳多個promise實例根吁;

注意员淫,當(dāng)里面多個promise實例狀態(tài)全部發(fā)生改變的時候,才會觸發(fā)promise.all击敌,返回的新的promise對象介返,后面才可以使用then等一些方法。

場景一:所有圖片加載完再添加到頁面中

Promise.race()的使用場景

????????有三個圖片沃斤,在三個不同的位置圣蝎,這個頁面需要加載其中一張圖片,但不知道這三個圖片哪個返回比較快衡瓶,也不關(guān)心哪個比較快徘公,但是知道這三個圖片的加載來源,加載出一個來源就可以哮针;所以就是說关面,先到先得,哪個先加載出來十厢,就顯示哪個缭裆;

Promise.race():格式,寫法和promise.all一樣寿烟;

race里面的promise實例澈驼,哪一個先改變了,就會觸發(fā)race的實例筛武,剩下的就不管了

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

Iterator接口可以看成是一個遍歷器缝其;

Iterator接口的作用:實現(xiàn)不同數(shù)據(jù)類型之間,統(tǒng)一讀取里面的數(shù)據(jù)徘六;

for...of循環(huán)的過程内边,就是在背后不斷的調(diào)用Iterator接口來達(dá)到這種形式;不同的數(shù)據(jù)結(jié)構(gòu)通過for...of統(tǒng)一的這種形式待锈,來達(dá)到讀取不同的數(shù)據(jù)結(jié)構(gòu)的目標(biāo)漠其,但是背后的Iterator接口是不同的;

數(shù)組循環(huán)中for..of與for ..in的區(qū)別:for..of循環(huán)的是數(shù)組中的每一項竿音,for ..in循環(huán)的是索引和屎;

Iterator接口寫法

簡單的Iterator接口寫法:[Symbol.iterator]()以方法的形式表示;

接口都有一個next():這個方法是用來查看是否還有數(shù)據(jù)春瞬,返回的是對象類型柴信,固定的有兩個屬性,value和done宽气,value返回的是數(shù)據(jù)中的值随常,done是boolean類型潜沦,true表示下面還有數(shù)據(jù),false表示沒有數(shù)據(jù)了绪氛。

Iterator自定義

Iterator接口也可以用來自定義;

for...of不可以循環(huán)對象唆鸡,可以通過Iterator接口來實現(xiàn)。

十三.Generator

Generator:異步編程的解決文案枣察,也可以說是一個狀態(tài)機(jī)争占;可以遍歷,語法就是一個函數(shù)询件;

異步編程有:回調(diào),promise唆樊,這個Generator相對于這兩個比較高級一些宛琅;

基本定義

Generator返回的就是一個Iterator接口

寫法,就是一個function后面緊跟著一個星號逗旁,function*(){}

以上得出嘿辟,Generator調(diào)用next()會一直找到函數(shù)中的return ,就會結(jié)果查找,done返回true片效;

上面的return 返回的是undefined所以找到這里就會結(jié)果查找红伦;

yield

yield語句本身沒有返回值,或者每次返回undefined淀衣;

next

next是可以帶參數(shù)的昙读,參數(shù)會給上一個yield的值;

實際應(yīng)用

作為狀態(tài)機(jī)的演示

說明:比如有a b c三種狀態(tài)描述一個事物膨桥,這個事物只存在三種狀態(tài)a b c蛮浑,永遠(yuǎn)沒有第四種狀態(tài);generator處理這種狀態(tài)最適合只嚣;

async與await

async與await:這兩個是generator的語法糖沮稚,就是把generator的function* (){}中的星號去掉,在function前面加async册舞,函數(shù)中的yield改成await蕴掏。其它的使用方法全部一樣;想執(zhí)行以下代碼,需要加一個babel的插件

實際使用場景

場景一调鲸,抽獎

前端如何做抽獎次數(shù)的限制荐类,當(dāng)抽獎次數(shù)用完后,提示用戶不可以再抽獎笙什。

重點是怎么計算當(dāng)前還有多少次蓝翰,之前的做法是設(shè)置一個全局變量,來保存當(dāng)前次數(shù),這樣非常不安全贯钩,如果對方知道這個次數(shù)的變量募狂,會隨意修改办素,這樣就無法攔截了;而且盡量不要把數(shù)據(jù)存放在全局變量中祸穷,影響頁面性能性穿;

下面使用generator來實現(xiàn);

場景二雷滚,長輪詢

長輪詢需曾,如何說服務(wù)端某一個數(shù)據(jù)定期變化,前端需要定期去取這個變化的數(shù)據(jù)祈远;

因為http是無狀態(tài)的鏈接呆万,取經(jīng)常變化的狀態(tài),可以使用websocket和長輪詢车份;

因為這個websocket兼容性不是很好谋减,所以一般經(jīng)常使用的就是長輪詢的方法;

之前的長輪詢是通過定時器扫沼,不斷的去取狀態(tài)出爹,使用generator可以讓頁面的代碼變的更優(yōu)雅。把相關(guān)業(yè)務(wù)區(qū)分開缎除;

十四.Decorator(修飾器)

概念:修飾器是一個函數(shù)严就,用來修改類的行為,修改類的行為器罐,可以理解為擴(kuò)展類的功能梢为,這個修飾器的修改范圍,只能是類的轰坊;

需要裝一個支持Decorator語法的包:npm install babel-plugin-transform-decorators-legacy ?--save-dev

安裝后抖誉,要在.babelrc文件中加一個插件:"plugins":["transform-decorators-legacy"]

修飾器的函數(shù)

函數(shù)中三個參數(shù)說明:

????target:要修改的類本身

????name:屬性名

????descriptor:屬性的描述對象

現(xiàn)實中實用案例

日志系統(tǒng)(埋點):這里是把埋點的相關(guān)邏輯放到了修飾器里面,業(yè)務(wù)相關(guān)邏輯代碼寫到一個class中衰倦;

這樣寫的好處:

1.把埋點系統(tǒng)抽離出來袒炉,成為一個可復(fù)用的模塊;如后續(xù)發(fā)現(xiàn)變化樊零,直接改埋點的相關(guān)代碼我磁,不需要動class中的代碼;

2.業(yè)務(wù)代碼也簡潔了驻襟,好維護(hù)了夺艰;

總結(jié)就是,使用修飾器沉衣,可以使代碼更有復(fù)用性郁副、簡潔、好維護(hù)M阆啊4婊选拔疚!

十五.Module模塊化

個人理解來講,一個一個的js文件就是一個個的模塊既荚,模塊中的變量代碼相互引用稚失。

模塊化要實現(xiàn)的目標(biāo),要解決功能單一恰聘;一個模塊一個功能句各;

引用方法

首先在js文件中,把需要暴露的變量導(dǎo)出晴叨,如圖:

導(dǎo)出方法一:

分句導(dǎo)出

導(dǎo)出方法二:

集合導(dǎo)出

在當(dāng)前文件中凿宾,導(dǎo)出后,使用import引入

引入方法:

1兼蕊、將導(dǎo)出的所有變量都寫在大括號中

? ? ? import {a,test,hello} from "./class/lesson18"

2初厚、大括號里,需要哪個寫哪個 ??

? ? ??import {a} from "./class/lesson18"

3遍略、如果遇到導(dǎo)出的變量非常多惧所,有好幾十甚至幾百個可以使用 import * as name from url 這種方式

? ? ? ?'*':表示文件中所有導(dǎo)出的變量骤坐;

? ? ? ?'name':是一個別名绪杏,另起一個名字,所有的變量都會存到這個對象中纽绍;

????????import * as test18 from "./class/lesson18"? ? // test18就是一個別名蕾久,這個對象中存放了所有的變量名

推薦使用第2種導(dǎo)出和第3種引入的方法,代碼簡潔明拌夏,操作方便僧著!


知識總結(jié)

使用es6注意事項

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市障簿,隨后出現(xiàn)的幾起案子盹愚,更是在濱河造成了極大的恐慌,老刑警劉巖站故,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件皆怕,死亡現(xiàn)場離奇詭異,居然都是意外死亡西篓,警方通過查閱死者的電腦和手機(jī)愈腾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岂津,“玉大人虱黄,你說我怎么就攤上這事∷背桑” “怎么了橱乱?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵辜梳,是天一觀的道長。 經(jīng)常有香客問我仅醇,道長冗美,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任析二,我火速辦了婚禮粉洼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘叶摄。我一直安慰自己属韧,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布蛤吓。 她就那樣靜靜地躺著宵喂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪会傲。 梳的紋絲不亂的頭發(fā)上锅棕,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機(jī)與錄音淌山,去河邊找鬼裸燎。 笑死,一個胖子當(dāng)著我的面吹牛泼疑,可吹牛的內(nèi)容都是我干的德绿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼退渗,長吁一口氣:“原來是場噩夢啊……” “哼移稳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起会油,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤个粱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后翻翩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體都许,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年体斩,在試婚紗的時候發(fā)現(xiàn)自己被綠了梭稚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡絮吵,死狀恐怖弧烤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤暇昂,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布莺戒,位于F島的核電站,受9級特大地震影響急波,放射性物質(zhì)發(fā)生泄漏从铲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一澄暮、第九天 我趴在偏房一處隱蔽的房頂上張望名段。 院中可真熱鬧,春花似錦泣懊、人聲如沸伸辟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽信夫。三九已至,卻和暖如春卡啰,著一層夾襖步出監(jiān)牢的瞬間静稻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工匈辱, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留振湾,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓梅誓,卻偏偏與公主長得像恰梢,于是被迫代替她去往敵國和親佛南。 傳聞我的和親對象是個殘疾皇子梗掰,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

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

  • 《ECMAScript6 入門》阮一峰 讀書筆記 let和constlet聲明的變量僅在塊級作用域內(nèi)有效,var聲...
    親愛的孟良閱讀 720評論 1 2
  • 強(qiáng)大的for-of循環(huán) ES6不會破壞你已經(jīng)寫好的JS代碼嗅回。目前看來及穗,成千上萬的Web網(wǎng)站依賴for-in循環(huán),其...
    Awe閱讀 7,515評論 2 7
  • ECMAScript 6.0( 以下簡稱ES6) 是JavaScript語言的下一代標(biāo)準(zhǔn)绵载。 ECMAScript和...
    EarthChen閱讀 440評論 0 0
  • 1. Promise 的含義 所謂Promise埂陆,簡單說就是一個容器,里面保存著某個未來才會結(jié)束的事件(通常是一個...
    ROBIN2015閱讀 490評論 0 0
  • 如果要讓我在中國以外選出一個最喜歡的國家娃豹,那一定就是英國了焚虱。我尤其愛那英國古典的味道。所以當(dāng)我開始有想法讀一些外國...
    長楓萬禮頌閱讀 5,465評論 15 88