在ES6以前我們用 function 來定義函數,還記得樓主剛學js那會兒老是把function寫錯 (╯‵□′)╯︵┻━┻,但是自從ES6中出現了箭頭函數以后,媽媽再也不擔心我寫成 fnuction了,那么我們下面開始正式學習!
基本語法:
- ES6允許使用“箭頭”(
=>
)定義函數。
let func = (num) => num;
- 上面的箭頭函數等同於:
let func = function (num) { return num; }
小伙伴們發現了什么?沒錯, ES6的箭頭函數去掉了function,使我們的代碼變得更加簡潔,下面再看看其他的寫法
- 如果箭頭函數不需要參數或需要多個參數,就使用一個圓括號代表參數部分。
var func = () => num; // 等同於 var func = function () { return num }; var sum = (num1, num2) => num1 + num2; // 等同於 var sum = function(num1, num2) { return num1 + num2; };
讓我們來看一個更喪心病狂的寫法~
- 如果箭頭函數只有一個參數,可以省略掉括號。
let func = num => 1; //等同於 let func = function (num) { return 1; }
- 如果箭頭函數的代碼塊部分多於一條語句,就要使用大括號將它們括起來,並且使用
return
語句返回。
var sum = (num1, num2) => { return num1 + num2; }
- 需要注意的一點:因為大括號被解釋成代碼塊,如果箭頭函數直接返回一個對象,那么必須要在大括號外面加上括號。
var porson = name => ({ name: name, age: "18" });
- 更加簡潔的表達式。
const isEven = n => n % 2 == 0;
const square = n => n * n;
上面代碼只用了兩行,就定義了兩個簡單的工具函數。如果不用箭頭函數要寫很多行代碼,而且不如這個結構清晰
- 箭頭函數的一個用處是簡化回調函數,例子如下。
// 正常函數寫法 [1,2,3].map(function (x) { return x * x; }); // 箭頭函數寫法 [1,2,3].map(x => x * x);
使用注意點:
- this指向問題
- 讓我們使用特定的例子來體現箭頭函數的this。
先來看看這段代碼:
let person = { name:'光頭強', init:function(){ //為body添加一個點擊事件,看看這個點擊后的this屬性有什么不同 document.body.onclick = function(){ alert(this.name);//?? this在瀏覽器默認是調用時的對象,可變的? alert(this); } } }
person.init();
如我們所願,第一個 alert 彈出的是 undefined,第二個是 body (object HTMLBodyElement);
再來看一段代碼:
let person = { name:'jike', init:function(){ //為body添加一個點擊事件,看看這個點擊后的this屬性有什么不同 document.body.onclick = ()=>{ alert(this.name);//?? this在瀏覽器默認是調用時的對象,可變的? } } } person.init();
答案是 jike ,答對了嗎?
- 其實箭頭函數本身沒有this,而自身的this會在函數聲明的時候做綁定,它是根據上級的function中的this來做綁定的
那么問題又來了,如果上級的function也是箭頭函數呢?
看看這段代碼:
let person = { name:'jike', init:()=>{ //為body添加一個點擊事件,看看這個點擊后的this屬性有什么不同 document.body.onclick = ()=>{ alert(this.name);//?? this在瀏覽器默認是調用時的對象,可變的? } } } person.init();
毫無疑問 this 會指向 window (object Window)。
- 總結出的結論就是:如果上級也是箭頭函數,再上級查找
2.箭頭函數的構造函數
- 問:箭頭函數可以做構造函數嗎?
- 答:不可以!
請看下面代碼:
function Person(p){ //完成初始化 this.name = p.name; }
這是沒有箭頭函數的構造函數,但是用了箭頭函數以后呢?
()=>{
......
}
等等....這是什么鬼!什么語法!不報錯才怪。我故意讓他報錯的?嘿,你還不信,那再來一種寫法。
var Person = (p)=>{ this.??? }
好的,我們給他加上變量,再等等....這 this 指向哪里?向上級去找?
- 根據上面代碼可以得到結論:當我們知道箭頭函數本沒有this,而是借的,構造函數自然不攻自破,所以,箭頭函數不能做構造函數。
3. 箭頭函數的 arguments
老規矩,先上代碼:
let func = (n1,n2)=>{
console.log(arguments);
}
func(2,3);
不用看了,答案是:報錯,Uncaught ReferenceError: arguments is not defined
- 箭頭函數沒有 arguments 嗎 ?到這里是不是想到了 this? 箭頭函數本身沒有this,可以通過向上級查找,那么 argument 呢?
我們來賭一把:
function func0(n1,n2,n3){ //[1, 2, 3] let func = (n1,n2)=>{ console.log(arguments); } func(); } func0(1,2,3);
恭喜你賭對了(可惜並沒有獎勵...)。
- 箭頭函數本身也沒有 arguments,如果該箭頭函數外部包含function,在函數的調用時,箭頭函數會將外部arguments拿來
總結:
- 在使用的時候,不必那么復雜,建議掌握一種就可以了 ()=>{}
- 看到極為簡單的情況也要認識let func = num => num;
- 一個參數: var f = num => num; 也可以 var f = (num) => num;
- 沒有參數: var f = ()=> 1;
- 多個參數: var f = (n1,n2)=> n1 + n2;
- 多行代碼: var f = (n1,n2)=>{//code.... return n1 + n2;}
箭頭函數的注意點:
- 箭頭函數本身沒有 this
- 自身的 this 會在函數聲明的時候做綁定
- 根據上級的function中的this來做綁定,如果上級也是箭頭函數,再上級查找,綁定以后就不再發生改變了,this不再多變
- **箭頭函數本沒有this,綁定后不再多變**
- 箭頭函數不可以做構造函數
- 箭頭函數本身也沒有arguments
- 如果該箭頭函數外部包含function,在函數的調用時,箭頭函數會將外部arguments拿來
感謝觀看,希望您看完能有一些收獲。
最后安利阮老師的ES6入門:http://es6.ruanyifeng.com