1.函數(shù)參數(shù)的默認(rèn)值
ES6 允許為函數(shù)的參數(shù)設(shè)置默認(rèn)值,即直接寫在參數(shù)定義的后面宠能。
注意:
(1)參數(shù)變量是默認(rèn)聲明的,不能用let和const再次聲明
(2)默認(rèn)參數(shù)值不是單純的傳值的而是惰性求值的
2.與解構(gòu)賦值默認(rèn)值結(jié)合使用
function foo({x,y=5}){
console.log(x,y)
}
foo({})
VM782:2 undefined 5
undefined
foo({x:3})
VM782:2 3 5
undefined
foo({x:3,y:8})
VM782:2 3 8
undefined
foo()
VM782:1 Uncaught TypeError: Cannot destructure property `x` of 'undefined' or 'null'.
因?yàn)楹瘮?shù)沒有提供默認(rèn)值鸭蛙,當(dāng)調(diào)用函數(shù)時(shí)參數(shù)為空或者不為對象類型時(shí)就會(huì)報(bào)錯(cuò)川尖,這里只是用了對象的解構(gòu)賦值的默認(rèn)值
function foo({x,y=5} = {})
{
console.log(x,y)
}
foo() // undefined 5
參數(shù)默認(rèn)值的位置
參數(shù)默認(rèn)值一般應(yīng)該是尾參數(shù),如果不是尾參數(shù)藻糖,一般是無法省略的淹冰,需要顯式輸入undefined ,輸入undefined可以觸發(fā)默認(rèn)值巨柒,輸入null則沒有這個(gè)效果
函數(shù)的length屬性
length屬性的含義是樱拴,該函數(shù)預(yù)期傳入的參數(shù)個(gè)數(shù)柠衍。函數(shù)指定了默認(rèn)值后,預(yù)傳入的參數(shù)個(gè)數(shù)就不包括這個(gè)參數(shù)了晶乔。rest參數(shù)也不會(huì)計(jì)入length屬性
另外如果默認(rèn)值不是尾參數(shù)珍坊,那么length屬性將不會(huì)再計(jì)算默認(rèn)值后面的參數(shù)了
作用域
一旦設(shè)置了參數(shù)的默認(rèn)值,函數(shù)進(jìn)行聲明初始化時(shí)正罢,參數(shù)會(huì)形成一個(gè)單獨(dú)的作用域(context)阵漏。等到初始化結(jié)束,這個(gè)作用域就會(huì)消失翻具。這種語法行為履怯,在不設(shè)置參數(shù)默認(rèn)值時(shí),是不會(huì)出現(xiàn)的呛占。
二虑乖、rest參數(shù)
ES6 引入 rest 參數(shù)(形式為...變量名),用于獲取函數(shù)的多余參數(shù)晾虑,這樣就不需要使用arguments對象了疹味。
res參數(shù)后面不能再有其他參數(shù)了
length屬性,不包括rest參數(shù)
三帜篇、嚴(yán)格模式
es6只要函數(shù)參數(shù)使用了默認(rèn)值糙捺、解構(gòu)賦值、或者擴(kuò)展運(yùn)算符笙隙,函數(shù)內(nèi)部就不能顯示設(shè)定為嚴(yán)格模式
因?yàn)橹荒茉诤瘮?shù)體中設(shè)置嚴(yán)格模式洪灯,然而參數(shù)卻是優(yōu)先于函數(shù)體執(zhí)行的,所以就矛盾了
四竟痰、name屬性
函數(shù)的name屬性签钩,返回該函數(shù)的函數(shù)名。
var f = function(){}//后面是匿名函數(shù)
es5 name會(huì)返'回'
es6 name會(huì)返回‘f’
五坏快、箭頭函數(shù)
注意
1.箭頭函數(shù)直接返回一個(gè)對象铅檩,必須要在對象外面加一個(gè)括號
2.箭頭函數(shù)可以和變量解構(gòu)結(jié)合使用
箭頭函數(shù)有幾個(gè)使用注意點(diǎn)。
(1)函數(shù)體內(nèi)的this對象莽鸿,就是定義時(shí)所在的對象昧旨,而不是使用時(shí)所在的對象。
function foo(){
setTimeout(()=>{
console.log(this.id)
},100)
}
function fbb(){
setTimeout(function(){
console.log(this.id)
},100)
}
var id = 21
foo.call({id:42}) ///42
fbb.call({id:42}) /// 21
(2)不可以當(dāng)作構(gòu)造函數(shù)祥得,也就是說兔沃,不可以使用new命令,否則會(huì)拋出一個(gè)錯(cuò)誤级及。
(3)不可以使用arguments對象乒疏,該對象在函數(shù)體內(nèi)不存在。如果要用饮焦,可以用 rest 參數(shù)代替缰雇。
(4)不可以使用yield命令入偷,因此箭頭函數(shù)不能用作 Generator 函數(shù)追驴。
箭頭函數(shù)沒有自己的this械哟,所以不能用call()、apply()殿雪、bind()這些方法去改變this的指向
六暇咆、雙冒號運(yùn)算符
函數(shù)綁定運(yùn)算符是并排的兩個(gè)冒號(::),雙冒號左邊是一個(gè)對象丙曙,右邊是一個(gè)函數(shù)爸业。該運(yùn)算符會(huì)自動(dòng)將左邊的對象,作為上下文環(huán)境(即this對象)亏镰,綁定到右邊的函數(shù)上面扯旷。
七、尾調(diào)用優(yōu)化
尾調(diào)用(Tail Call)是函數(shù)式編程的一個(gè)重要概念索抓,本身非常簡單钧忽,一句話就能說清楚,就是指某個(gè)函數(shù)的最后一步是調(diào)用另一個(gè)函數(shù)逼肯。
尾調(diào)用不一定出現(xiàn)在函數(shù)尾部耸黑,只要是最后一步操作即可。
function f() {
let m = 1;
let n = 2;
return g(m + n);
}
f();
// 等同于
function f() {
return g(3);
}
f();
// 等同于
g(3);
上面代碼中篮幢,如果函數(shù)g不是尾調(diào)用大刊,函數(shù)f就需要保存內(nèi)部變量m和n的值、g的調(diào)用位置等信息三椿。但由于調(diào)用g之后缺菌,函數(shù)f就結(jié)束了,所以執(zhí)行到最后一步搜锰,完全可以刪除f(x)的調(diào)用幀伴郁,只保留g(3)的調(diào)用幀。
這就叫做“尾調(diào)用優(yōu)化”(Tail call optimization)纽乱,即只保留內(nèi)層函數(shù)的調(diào)用幀蛾绎。如果所有函數(shù)都是尾調(diào)用,那么完全可以做到每次執(zhí)行時(shí)鸦列,調(diào)用幀只有一項(xiàng)租冠,這將大大節(jié)省內(nèi)存。這就是“尾調(diào)用優(yōu)化”的意義薯嗤。
八顽爹、尾逗號
因此新的語法允許定義和調(diào)用時(shí),尾部直接有一個(gè)逗號骆姐。