箭頭函數


在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);

使用注意點:

  1. 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM