新增的常用特性:
1叁扫、Let 和Const?2、模板字符串 3畜埋、對(duì)象屬性縮寫 4莫绣、箭頭函數(shù)?5、新增的對(duì)象操作方法 6悠鞍、解構(gòu)賦值 7对室、函數(shù)的擴(kuò)展——默認(rèn)參數(shù) 8、Promises? 9咖祭、Class 10掩宜、Modules
一、let和const
1.塊級(jí)作用域么翰,在塊級(jí)作用域外訪問(wèn)不到牺汤;
2.無(wú)變量提升,先聲明后使用浩嫌,否則報(bào)錯(cuò)檐迟;
3.擁有暫時(shí)性死區(qū),即使與全局變量同名码耐,在塊級(jí)作用域中仍訪問(wèn)不到let定義的全局同名變量追迟。原因是如果區(qū)塊中存在let和const命令,這個(gè)區(qū)塊對(duì)這些命令聲明的變量骚腥,從一開(kāi)始就形成了封閉作用域敦间。凡是在聲明之前就使用這些變量就會(huì)報(bào)錯(cuò);即使是typeof操作符也會(huì)報(bào)錯(cuò);
4.let和const定義的變量不會(huì)成為window的屬性每瞒,而var和function的全局聲明會(huì)自動(dòng)綁定到window對(duì)象金闽;
二、模板字符串
1.方便的拼接字符串以及插入變量剿骨;
如:`my name is ${某個(gè)變量}`代芜;可寫多行;
三浓利、對(duì)象屬性縮寫
1.同名屬性可以縮寫:
let obj = {
name// 等同于name:name
}
四挤庇、箭頭函數(shù)?
1.箭頭函數(shù)簡(jiǎn)化了函數(shù)的書寫方式,使得書寫更加優(yōu)雅贷掖;
2.箭頭函數(shù)綁定了上下文的this嫡秕,使得this指向符合預(yù)期,而不必使用 _this?=?this??或.bind(this)獲得預(yù)期的this值
五苹威、新增的對(duì)象操作方法?
1.Object.is() 解決=== 的兩個(gè)問(wèn)題昆咽;
ES5 比較兩個(gè)值是否相等,只有兩個(gè)運(yùn)算符:相等運(yùn)算符(==)和嚴(yán)格相等運(yùn)算符(===)牙甫。它們都有缺點(diǎn)掷酗,前者會(huì)自動(dòng)轉(zhuǎn)換數(shù)據(jù)類型,后者的NaN不等于自身窟哺,以及+0等于-0
Object.is(+0,-0) // false
Object.is(NaN,NaN) // true
2.Object.assign()
Object.assign(target,source1,source2);
(1)Object.assign方法用于對(duì)象的合并泻轰,將源對(duì)象(source)的所有可枚舉屬性,復(fù)制到目標(biāo)對(duì)象(target)且轨;
(2)目標(biāo)對(duì)象有同名屬性會(huì)覆蓋源對(duì)象浮声;
(3)如果該參數(shù)不是對(duì)象,則會(huì)先轉(zhuǎn)成對(duì)象旋奢,然后返回泳挥;
(4)如果undefined和null在target參數(shù)位置則報(bào)錯(cuò),否則轉(zhuǎn)換不了對(duì)象而跳過(guò)至朗;
(5)Object.assign方法實(shí)行的是淺拷貝屉符,而不是深拷貝;
常見(jiàn)用途:??
(1)為對(duì)象添加屬性
(2)為對(duì)象添加方法
(3)克隆對(duì)象?Object.assign({},origin)
(4)合并多個(gè)對(duì)象?Object.assign(target,...sources)
(5)為屬性指定默認(rèn)值?Object.assign({},DEFAULTS,options)?
3.Object.getOwnPropertyDescriptors()
返回某個(gè)對(duì)象屬性的描述對(duì)象(descriptor)
4.__proto__屬性爽丹,Object.setPrototypeOf()筑煮,Object.getPrototypeOf()
__proto__調(diào)用的是Object.prototype.__proto__辛蚊,無(wú)論從語(yǔ)義的角度粤蝎,還是從兼容性的角度,都不要使用這個(gè)屬性袋马,而是使用下面的Object.setPrototypeOf()(寫操作)初澎、Object.getPrototypeOf()(讀操作)、Object.create()(生成操作)
5.Object.keys(),Object.values()碑宴,Object.entries()?
ES5 引入了Object.keys方法软啼,返回一個(gè)數(shù)組,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵名延柠。ES2017 引入了跟Object.keys配套的Object.values和Object.entries祸挪,作為遍歷一個(gè)對(duì)象的補(bǔ)充手段,供for...of循環(huán)使用贞间。
六贿条、解構(gòu)賦值? ? ?
ES6 允許按照一定模式,從數(shù)組和對(duì)象中提取值增热,對(duì)變量進(jìn)行賦值整以,這被稱為解構(gòu)(Destructuring);只要等號(hào)兩邊的模式相同峻仇,左邊的變量就會(huì)被賦予對(duì)應(yīng)的值公黑。
1.解構(gòu)不成功,變量的值就等于undefined摄咆;
2.如果是數(shù)組結(jié)構(gòu)凡蚜,等號(hào)的右邊不是數(shù)組(或者嚴(yán)格地說(shuō),不是可遍歷的結(jié)構(gòu))豆同,那么將會(huì)報(bào)錯(cuò)番刊;
3.解構(gòu)賦值允許指定默認(rèn)值。ES6 內(nèi)部使用嚴(yán)格相等運(yùn)算符(===)影锈,判斷一個(gè)位置是否有值芹务。所以,只有當(dāng)一個(gè)數(shù)組成員嚴(yán)格等于undefined鸭廷,默認(rèn)值才會(huì)生效枣抱;
4.對(duì)象的解構(gòu)與數(shù)組有一個(gè)重要的不同。數(shù)組的元素是按次序排列的辆床,變量的取值由它的位置決定佳晶;而對(duì)象的屬性沒(méi)有次序,變量必須與屬性同名讼载,才能取到正確的值轿秧;
5.對(duì)象的解構(gòu)賦值的內(nèi)部機(jī)制,是先找到同名屬性咨堤,然后再賦給對(duì)應(yīng)的變量菇篡;
6.對(duì)象的解構(gòu)賦值可以取到繼承的屬性;
7.函數(shù)的參數(shù)也可以使用解構(gòu)賦值
七一喘、函數(shù)的擴(kuò)展——默認(rèn)參數(shù)??
1.ES6 允許為函數(shù)的參數(shù)設(shè)置默認(rèn)值驱还,即直接寫在參數(shù)定義的后面。
2.參數(shù)變量是默認(rèn)聲明的,所以不能用let或const再次聲明议蟆。
3.使用參數(shù)默認(rèn)值時(shí)闷沥,函數(shù)不能有同名參數(shù)。
4.參數(shù)默認(rèn)值不是傳值的咐容,而是每次都重新計(jì)算默認(rèn)值表達(dá)式的值舆逃。也就是說(shuō),參數(shù)默認(rèn)值是惰性求值的戳粒。
5.與解構(gòu)賦值默認(rèn)值可以結(jié)合使用颖侄;
6.定義了默認(rèn)值的參數(shù),應(yīng)該是函數(shù)的尾參數(shù)享郊,如果不是览祖,則需顯式傳入undefined,不可省略否則報(bào)錯(cuò)炊琉;
7.一旦設(shè)置了參數(shù)的默認(rèn)值展蒂,函數(shù)進(jìn)行聲明初始化時(shí),參數(shù)會(huì)形成一個(gè)單獨(dú)的作用域(context)苔咪。等到初始化結(jié)束锰悼,這個(gè)作用域就會(huì)消失。這種語(yǔ)法行為团赏,在不設(shè)置參數(shù)默認(rèn)值時(shí)箕般,是不會(huì)出現(xiàn)的。
8.(1)ES6 引入 rest 參數(shù)(形式為...變量名)舔清,用于獲取函數(shù)的多余參數(shù)丝里,這樣就不需要使用arguments對(duì)象了。rest 參數(shù)搭配的變量是一個(gè)數(shù)組体谒,該變量將多余的參數(shù)放入數(shù)組中杯聚;(2)rest 參數(shù)之后不能再有其他參數(shù)(即只能是最后一個(gè)參數(shù)),否則會(huì)報(bào)錯(cuò)? ?
八抒痒、Promises??
Promise 是異步編程的一種解決方案幌绍,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ì)象惨缆,從它可以獲取異步操作的消息糜值。
1.Promise對(duì)象代表一個(gè)異步操作,有三種狀態(tài):pending(進(jìn)行中)坯墨、fulfilled(已成功寂汇,也可叫resolved)和rejected(已失敗)捣染;
2.狀態(tài)不受外界影響骄瓣,且一旦狀態(tài)改變,就不會(huì)再變耍攘;
缺點(diǎn):
1.無(wú)法取消Promise榕栏,一旦新建它就會(huì)立即執(zhí)行,無(wú)法中途取消蕾各;
2.不設(shè)置回調(diào)函數(shù)扒磁,Promise內(nèi)部拋出的錯(cuò)誤,不會(huì)反應(yīng)到外部式曲;
3.當(dāng)處于pending狀態(tài)時(shí)妨托,無(wú)法得知目前進(jìn)展到哪一個(gè)階段(剛剛開(kāi)始還是即將完成);
用法:
1.ES6 規(guī)定吝羞,Promise對(duì)象是一個(gè)構(gòu)造函數(shù)兰伤,用來(lái)生成Promise實(shí)例;
2.Promise構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù)钧排,該函數(shù)的兩個(gè)參數(shù)分別是resolve和reject敦腔。它們是兩個(gè)函數(shù),由 JavaScript 引擎提供恨溜;
3.resolve函數(shù)的作用是符衔,將Promise對(duì)象的狀態(tài)從“未完成”變?yōu)椤俺晒Α保磸?pending 變?yōu)?resolved),在異步操作成功時(shí)調(diào)用糟袁,并將異步操作的結(jié)果柏腻,作為參數(shù)傳遞出去;
4.reject函數(shù)的作用是系吭,將Promise對(duì)象的狀態(tài)從“未完成”變?yōu)椤笆 保磸?pending 變?yōu)?rejected)五嫂,在異步操作失敗時(shí)調(diào)用,并將異步操作報(bào)出的錯(cuò)誤肯尺,作為參數(shù)傳遞出去沃缘;
5.Promise實(shí)例生成以后,可以用then方法分別指定resolved狀態(tài)和rejected狀態(tài)的回調(diào)函數(shù)则吟。
6.then方法可以接受兩個(gè)回調(diào)函數(shù)作為參數(shù)槐臀。第一個(gè)回調(diào)函數(shù)是Promise對(duì)象的狀態(tài)變?yōu)閞esolved時(shí)調(diào)用,第二個(gè)回調(diào)函數(shù)是Promise對(duì)象的狀態(tài)變?yōu)閞ejected時(shí)調(diào)用氓仲。其中水慨,第二個(gè)函數(shù)是可選的得糜,不一定要提供。這兩個(gè)函數(shù)都接受Promise對(duì)象傳出的值作為參數(shù)晰洒。建議使用then().catch(),而不是兩個(gè)回調(diào)函數(shù)朝抖;
7.Promise.prototype.then()同第6點(diǎn);
8.Promise.prototype.catch() 這方法是.then(null, rejection)或.then(undefined, rejection)的別名谍珊,用于指定發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)治宣。
9.Promise.prototype.finally()?finally方法用于指定不管 Promise 對(duì)象最后狀態(tài)如何,都會(huì)執(zhí)行的操作砌滞。該方法是 ES2018 引入標(biāo)準(zhǔn)的侮邀。
10.Promise.all()?接受一個(gè)數(shù)組作為參數(shù),數(shù)組里都是 Promise 實(shí)例贝润,如果不是绊茧,就會(huì)先調(diào)用下面講到的Promise.resolve方法,將參數(shù)轉(zhuǎn)為 Promise 實(shí)例打掘,再進(jìn)一步處理按傅;
例如:const p=Promise.all([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ù)古瓤。
11.Promise.race()
const p=Promise.race([p1,p2,p3]);
只要p1止剖、p2、p3之中有一個(gè)實(shí)例率先改變狀態(tài)落君,p的狀態(tài)就跟著改變穿香。那個(gè)率先改變的 Promise 實(shí)例的返回值,就傳遞給p的回調(diào)函數(shù)绎速。
12.Promise.resolve()?將現(xiàn)有對(duì)象轉(zhuǎn)為 Promise 對(duì)象皮获,有4條規(guī)則;
13.Promise.reject() Promise.reject(reason)方法也會(huì)返回一個(gè)新的 Promise 實(shí)例纹冤,該實(shí)例的狀態(tài)為rejected洒宝。
14.Promise.try()?不知道或者不想?yún)^(qū)分购公,函數(shù)f是同步函數(shù)還是異步操作,但是想用 Promise 來(lái)處理它雁歌。
應(yīng)用:?
const preloadImage=function(path){
return new Promise(function(resolve,reject){
const image=new Image();
image.onload=resolve;
image.onerror=reject;
image.src=path;
})
};
九宏浩、class?
引入了 Class(類)這個(gè)概念,作為對(duì)象的模板将宪。通過(guò)class關(guān)鍵字,可以定義類橡庞;
ES6 的class可以看作只是一個(gè)語(yǔ)法糖较坛,它的絕大部分功能,ES5 都可以做到扒最,新的class寫法只是讓對(duì)象原型的寫法更加清晰丑勤、更像面向?qū)ο缶幊痰恼Z(yǔ)法而已;
functionPoint(x,y){this.x=x;this.y=y;}
Point.prototype.toString=function(){return'('+this.x+', '+this.y+')';};
等同于:
classPoint{
? ?constructor(x,y){this.x=x;this.y=y;}
? ?toString(){
????????return'('+this.x+', '+this.y+')';
????}
}
1.類和模塊的內(nèi)部吧趣,默認(rèn)就是嚴(yán)格模式法竞,所以不需要使用use strict指定運(yùn)行模式
2.類不存在變量提升(hoist),這一點(diǎn)與 ES5 完全不同
3.Class 可以通過(guò)extends關(guān)鍵字實(shí)現(xiàn)繼承
4.子類必須在constructor方法中調(diào)用super方法强挫,否則新建實(shí)例時(shí)會(huì)報(bào)錯(cuò)岔霸。這是因?yàn)樽宇愖约旱膖his對(duì)象,必須先通過(guò)父類的構(gòu)造函數(shù)完成塑造俯渤,得到與父類同樣的實(shí)例屬性和方法呆细,然后再對(duì)其進(jìn)行加工,加上子類自己的實(shí)例屬性和方法八匠。如果不調(diào)用super方法絮爷,子類就得不到this對(duì)象
5.ES5 的繼承,實(shí)質(zhì)是先創(chuàng)造子類的實(shí)例對(duì)象this梨树,然后再將父類的方法添加到this上面(Parent.apply(this))坑夯。ES6 的繼承機(jī)制完全不同,實(shí)質(zhì)是先將父類實(shí)例對(duì)象的屬性和方法抡四,加到this上面(所以必須先調(diào)用super方法)柜蜈,然后再用子類的構(gòu)造函數(shù)修改this。
十指巡、modules?
在 ES6 之前跨释,社區(qū)制定了一些模塊加載方案,最主要的有 CommonJS 和 AMD 兩種厌处。前者用于服務(wù)器鳖谈,后者用于瀏覽器。ES6 在語(yǔ)言標(biāo)準(zhǔn)的層面上阔涉,實(shí)現(xiàn)了模塊功能缆娃,而且實(shí)現(xiàn)得相當(dāng)簡(jiǎn)單捷绒,完全可以取代 CommonJS 和 AMD 規(guī)范,成為瀏覽器和服務(wù)器通用的模塊解決方案贯要。
ES6 模塊的設(shè)計(jì)思想是盡量的靜態(tài)化暖侨,使得編譯時(shí)就能確定模塊的依賴關(guān)系,以及輸入和輸出的變量崇渗。CommonJS 和 AMD 模塊字逗,都只能在運(yùn)行時(shí)確定這些東西。
ES6 模塊不是對(duì)象宅广,而是通過(guò)export命令顯式指定輸出的代碼葫掉,再通過(guò)import命令輸入。
1.ES6 的模塊自動(dòng)采用嚴(yán)格模式
2.export 命令
export var firstName='Michael';
或?var firstName='Michael'; export{firstName};
export function multiply(x,y){return x*y;};
export輸出的變量就是本來(lái)的名字跟狱,但是可以使用as關(guān)鍵字重命名
export命令規(guī)定的是對(duì)外的接口俭厚,必須與模塊內(nèi)部的變量建立一一對(duì)應(yīng)關(guān)系,而不能導(dǎo)出一個(gè)值驶臊,如export m;
export語(yǔ)句輸出的接口挪挤,與其對(duì)應(yīng)的值是動(dòng)態(tài)綁定關(guān)系,即通過(guò)該接口关翎,可以取到模塊內(nèi)部實(shí)時(shí)的值扛门。
export命令可以出現(xiàn)在模塊的任何位置,只要處于模塊頂層就可以纵寝。
3.import命令
import命令接受一對(duì)大括號(hào)尖飞,里面指定要從其他模塊導(dǎo)入的變量名。大括號(hào)里面的變量名店雅,必須與被導(dǎo)入模塊對(duì)外接口的名稱相同政基;
可以使用as關(guān)鍵字,將輸入的變量重命名闹啦;
import命令輸入的變量都是只讀的沮明,因?yàn)樗谋举|(zhì)是輸入接口。也就是說(shuō)窍奋,不允許在加載模塊的腳本里面荐健,改寫接口;
import命令具有提升效果,會(huì)提升到整個(gè)模塊的頭部琳袄,首先執(zhí)行;
import是靜態(tài)執(zhí)行江场,所以不能使用表達(dá)式和變量;
import語(yǔ)句會(huì)執(zhí)行所加載的模塊,多次重復(fù)執(zhí)行同一句import語(yǔ)句,那么只會(huì)執(zhí)行一次窖逗,而不會(huì)執(zhí)行多次;
import可以使用整體加載址否,即用星號(hào)(*)指定一個(gè)對(duì)象,所有輸出值都加載在這個(gè)對(duì)象上面,import * as xxx from 'xxx';
4.export default 命令
export default就是輸出一個(gè)叫做default的變量或方法碎紊,然后系統(tǒng)允許你為它取任意名字,故import的時(shí)候可以隨意取名字佑附;
export default也可以用來(lái)輸出類樊诺。
5.export 與 import 的復(fù)合寫法
如果在一個(gè)模塊之中,先輸入后輸出同一個(gè)模塊音同,import語(yǔ)句可以與export語(yǔ)句寫在一起词爬;
export{foo as myFoo} from 'my_module';// 接口改名?
6.import()動(dòng)態(tài)加載
import命令能夠接受什么參數(shù),import()函數(shù)就能接受什么參數(shù)权均,兩者區(qū)別主要是后者為動(dòng)態(tài)加載顿膨;
(1)按需加載
(2)條件加載
(3)動(dòng)態(tài)的模塊路徑