前言
其實這本書已經(jīng)看完很久了榕订。前幾天突然有人在微信群里分享了別人的翻譯版本店茶。如果有些人會覺得這本書英文比較難理解,還是可以去找翻譯版的看一看劫恒。
我還是接著回顧一下知識點吧贩幻。
參數(shù)默認(rèn)值
解決的問題
ES5中我們經(jīng)常要寫出這樣的代碼:
var a = function(timeout,callback){
timeout= timeout|| 2000;
callback = callback || function(){};
}
傳統(tǒng)的方式有兩個方面困擾
- 如果timeout或callback傳入的值是0,"", null等會被默認(rèn)值替代
- 繁瑣
下面是ES6的寫法:
var a = function(timeout = 2000,callback=function(){}){
}
此時只有傳參進(jìn)來的值是undefined两嘴,才會用默認(rèn)參數(shù)復(fù)制
等同于
timeout = (typeof timeout !== "undefined")? timeout : 2000;
默認(rèn)參數(shù)帶來的arguments的變化
首先丛楚,假定一個函數(shù)
var a = function(first,second){
//<1>
fist = "c";
second = "d"
//<2>
}
a("a","b");
- ES5 非嚴(yán)格模式下
無論是1處還是在2處
first === arguments[0];
second === arguments[1];
- ES5 嚴(yán)格模式
//1處
first === arguments[0];
second === arguments[1];
//2處
first !== arguments[0];
second !== arguments[1];
- ES6中默認(rèn)參數(shù)的情況
var a = function(first,second = "a"){
//first === arguments[0]
//second !== arguments[1]
fist = "c";
second = "d"
//first !== arguments[0]
//second !== arguments[1]
}
a("a","b");
默認(rèn)參數(shù)的使用
- 不僅可以賦值,還可以使函數(shù)返回值
var getValue = function(a){
return a;
}
var a = function(first, second = getValue(1)){
}
- 由于second 默認(rèn)參數(shù)是后于first解析的,還可以這樣:
var a = function(first = 1, second = getValue(first)){
}
下面是會拋錯的憔辫,因為默認(rèn)參數(shù)相當(dāng)于let聲明鸯檬,是會有TDZ的。
var a = function(first = = getValue(second), second = 1){
}
rest參數(shù)
某些時候你需要用到rest參數(shù)去簡化函數(shù)的傳參
var a = function(first,...other){
}
需要注意以下兩點:
- rest參數(shù)必須是參數(shù)的最后一個
var a = function(first,...other,third){ //error
}
- 不能用在對象字面量set的時候
var a = {
set name(...value){//error
}
}
//因為對象字面量的參數(shù)只允許有一個
對Function 構(gòu)造函數(shù)的增強
- 允許使用默認(rèn)參數(shù)螺垢,示例如下:
var a = new Function("first","second = first", "return first + second");
- 允許使用rest參數(shù)喧务,示例如下:
var a = new Function("...args", "return args[0]");
擴(kuò)散操作符...
擴(kuò)散操作與rest參數(shù)有密切關(guān)系
rest參數(shù):允許把多個獨立的參數(shù)變?yōu)閿?shù)組
擴(kuò)散操作符: 允許把數(shù)組切割成獨立的參數(shù)
使用場景:
需要使用apply調(diào)用的場合;
函數(shù)的name屬性
匿名函數(shù)表達(dá)式的錯誤難以調(diào)試,ES6為所有函數(shù)添加了name屬性枉圃。
- 函數(shù)聲明和函數(shù)表達(dá)式
function dosomething(){}
//dosomething.name : "dosomething"
var doAnotherthing(){}
//doAnotherthing.name: "doAnotherthing"
- 其他情況
var dosomething = function dosomethingElse(){}
//dosomething.name : "dosomethingElse";
var person = {
get firstName(){},
sayName:function(){}
}
//person.firstName.name: "get firstName";
//person.sayName.name:"sayName";
var dosomething = function(){};
//dosomething.bind().name:"bound dosomething";
//(new Function()).name : "anonymous";
闡明函數(shù)的兩種使用目的
在ES5中功茴,調(diào)用函數(shù)時用new和不用new有兩種不同的結(jié)果
function Person(name){
this.name = name;
}
//1
var person = new Person("ali");
//2
var notPerson = Person("ali");
比如說,在1調(diào)用的時候孽亲,返回了一個對象賦值給person,并將person.name設(shè)置為ali坎穿;而在2調(diào)用時,并
未返回值返劲,并在global對象上創(chuàng)建了一個name屬性
在ES6中玲昧,使用new則調(diào)用內(nèi)部的[[construct]]方法實現(xiàn)這一效果,不使用new則調(diào)用內(nèi)部的[[call]]方
法
注篮绿,不是所有的函數(shù)都有這兩個內(nèi)部方法孵延,箭頭函數(shù)就沒有。
new.target
在ES5中如果要判斷函數(shù)是否用new方式調(diào)用亲配,一般用instanceof尘应,較為繁瑣。
ES6增加了new.target
- 如果通過[[call]]調(diào)用吼虎,則new.target === undefined
- 如果通過[[construct]]調(diào)用犬钢,則new.targe === 這個類名;
- 在函數(shù)外使用new.target會拋錯
函數(shù)在塊級作用域內(nèi)狀況
總所周知的一個bug
在ES3及以前,理論上講函數(shù)聲明在塊級作用域會拋錯思灰,但基本上所有的瀏覽器都支持將函數(shù)寫在塊級作
用域內(nèi)玷犹,但實現(xiàn)方式各有差異。
ES5中嚴(yán)格模式下洒疚, 函數(shù)聲明在塊級作用域下會拋錯歹颓。
ES6嚴(yán)格模式下,函數(shù)聲明在塊級作用域的表現(xiàn)如同用let聲明一樣拳亿,只在塊級作用域有效晴股,有TDZ。
ES6非嚴(yán)格模式下肺魁,函數(shù)聲明在塊級作用域的表現(xiàn)如同用var聲明一樣电湘。
箭頭函數(shù)
- 沒有this,super,arguments,和new.target綁定
- 不能用new調(diào)用
- 沒有原型
箭頭函數(shù)的語法
let reflect = value =>value;
//等同于
let reflect = function(value){
return value;
}
let sum (num1,num2)=>num1+num2;
//等同于
let sum = function(num1,num2){
return num1+num2;
}
let getName ()=>"ali";
//等同于
let getName = function(){
return "ali";
}
//等同于
let getName ()=>{
return "ali";
}
//等同于
let getName ()=> ("ali")
尾遞歸優(yōu)化
ES6針對遞歸函數(shù)進(jìn)行了優(yōu)化鹅经,不過有幾點限制寂呛。
- 尾遞歸調(diào)用不需要調(diào)用當(dāng)前棧的變量(所以閉包是不行的)
- 函數(shù)在遞歸調(diào)用返回后不需要有進(jìn)一步的操作
- 尾遞歸調(diào)用的結(jié)果必須有返回函數(shù)值