1. 箭頭函數的特性
1.1 別的函數有單獨的this,箭頭函數沒有
如果是該函數是一個對象中的構造函數,所以判斷this很重要的標準就是判斷該是不是函數的構造函數,this指針指向一個該對象本身;
箭頭函數不會創建自己的this,它只會從自己的作用域鏈的上一層繼承this,定義時的上一層,不是調用時的上一層 ,這樣看起來,箭頭函數定義時沒有給自己留this,也就是沒有單獨的this指針。
如果不理解,可以看看後面的前2個helloWorld代碼區別。
造成的影響:
- call/apply/bind綁定對象失效
也因爲箭頭函數沒有自己的this指針,通過call()
或apply()
方法調用一個箭頭函數定義的函數時,只能傳遞該箭頭的參數,而不能傳遞綁定this(即call/bind/apply的第一個綁定調用對象的參數失效!箭頭函數沒有這個容納該指針的設置。
結論1:箭頭函數只會從自己的作用域鏈的上一層繼承this(定義時的上一層,不是調用時的上一層)
結論2:call/apply/bind調用一個箭頭函數定義的函數,第一個參數失效。
1.2 箭頭函數不綁定arguments
要理解箭頭函數不綁定arguments,先理解什麼叫做函數綁定argments
function foo(n){
console.log(arguments[0])
var foo2 = function(n){console.log(arguments[0])}
return foo2()
}
foo(1)
//1
//undefined
結論3:如果函數綁定了arguments,那麼嵌套函數之間的arguments對象是不一樣的。
而在箭頭函數就不一樣了,
function foo(n){
console.log(arguments[0])
var foo2 = (n)=>{console.log(arguments[0])}
return foo2()
}
foo(1)
//1
//1
結論4:箭頭函數是沒有自己的arguments,它直接引用了外層函數的arguments
1.3 箭頭函數不能使用 new 操作符
1.4 箭頭函數不能使用 prototype屬性
1.5 箭頭函數不能用作 Generator 函數
箭頭函數不能用作函數生成器(Generator
),除非是嵌套在已經用作函數生存器的函數內。
2. helloWorld挑戰
2.1 helloThis
需求:
定義一個虛擬人物,對象爲Person,它只要被構造(時鐘在構造函數裏面),就會1秒就長一歲(age),每長一歲都會console.log一下“我現在x歲啦!”
function Person(){
this.age = 0
var that = this
setInterval(function growUp(){
console.log("我現在"+(that.age++)+"歲啦")
},1000)
}
var p = new Person();
2.2 helloArrowThis
需求:
定義一個虛擬人物,對象爲Person,它只要被構造(時鐘在構造函數裏面),就會1秒就長一歲(age),每長一歲都會console.log一下“我現在x歲啦!"
請用過箭頭函數來解決this問題。
function Person (){
this.age = 0
setInterval(()=>{
console.log("我現在"+(this.age++)+"歲啦!")
},1000)
}
var p = new Person()
2.3 helloArrowArg
需求:
指定一個可以求圓的周長和圓的面積的函數,第一個參數是半徑r,第二個參數是決定求周長還是面積
function howCir(r,option=1){
var cir = () => 2*3.14*arguments[0]
var area = ()=>arguments[0]*arguments[0]*3.14
switch(option){
case 1: return cir()
case 2: return area()
default:return cir()
}
}