箭頭函數

基本用法

在ES6中容許使用 => 來定義函數,以下:javascript

var f = a => a;
    console.log(f(1)); //1

就等同於java

var f = function(a){
         return a;
    }
    console.log(f(1)); //1

從上面能夠看出,在箭頭左側的是表明參數,若參數只有一個,()能夠省略,箭頭右側的表示函數代碼塊,若代碼塊裏面是個返回值,則{}能夠省略不寫app

1.無參數狀況

若箭頭函數不須要參數,則左側用()代替,以下:函數

var f = () => {
      console.log("無參數狀況");
   }
    f();//無參數狀況

2.有參數狀況

var f = (a, b) => {
        return a+b;
   }
    console.log(f(1,2)); //3
var f = a => a;
 console.log(f(1)); //1

若是箭頭函數有參數,則須要用()括起來,若只有一個參數,括號能夠省略不寫this

在這裏要注意一個狀況,就是當箭頭函數直接返回一個對象的時候,以下:spa

var f = () => {name:'liming', age:22}; //報錯
    console.log(f());

這樣寫確定是報錯的,由於{}執行時變成代碼塊,會去運行代碼,因此要用一個()括起來才能夠,以下:code

var f = () => ({name:'liming', age:22}); 
console.log(f());

執行結果爲:對象

{name: "liming", age: 22}

以上這個寫法纔是正確的ip

箭頭函數注意點

1.this指向

var a = '全局變量a';
    var obj={
        a:'局部變量a',
        fn1:function(){
            console.log(this.a);
        },
        fn2:()=>{
            console.log(this.a);
        }
    }
    obj.fn1();
    obj.fn2();

輸出結果爲:作用域

局部變量a
全局變量a

普通函數的this咱們知道是指向最近的一個對象,而箭頭函數的this其實是指向定義時的this,好比把上面代碼改成:

var obj={
        a:'局部變量a',
        fn1:function(){
            console.log(this.a);
        },
        fn2:()=>{
            console.log(this.a);
        }
    }
    obj.fn1();
    obj.fn2();

輸出結果爲:

局部變量a
undefined

此時由於箭頭函數是指向全局的,全局沒有變量a則輸出undefined,這裏的fn1和fn2都是全局函數,因此箭頭函數this指向的是定義時的全局,而普通函數的this指向的是最近的一個對象

上面若是那個例子不太明白,能夠再看下以下例子:

this.a = '全局a';
    function Timer() {
         this.a = 'timer中的a';
        // 普通函數
        setTimeout(function () {
            console.log('普通函數:', this.a);
        });

        // 箭頭函數
        setTimeout(() => {
            console.log('箭頭函數:',this.a);
    });
    }
   new Timer();

輸出結果爲:

普通函數: 全局a
箭頭函數: timer中的a

這裏普通函數會指向全局是由於,距離普通函數最近的對象是setTimeOut,而setTimeOut是掛在全局做用域中,因此普通函數指向全局,箭頭函數指向的是定義時的對象,箭頭函數是在Timer中定義的,因此箭頭函數指向Timer

若是把以上代碼改成以下:

this.a = '全局a';
    function Timer() {
         this.a = 'timer中的a';
        // 普通函數
        setTimeout(function () {
            console.log('普通函數:', this.a);
        });

        // 箭頭函數
        setTimeout(() => {
            console.log('箭頭函數:',this.a);
    });
    }
   Timer();

輸出結果:

普通函數: timer中的a
箭頭函數: timer中的a

這個是爲何呢,由於若是是new Timer至關因而構造函數,構造了一個對象,若是是Timer()就至關因而調用函數Timer()這二者仍是有區別的,若是是調用函數Timer(),這個時候this的指向都是全局,在局部修改this.a會覆蓋全局的this.a

經過以上,咱們能夠知道普通函數跟箭頭函數this指向的區別是:

普通函數: this指向最靠近的一個對象

箭頭函數: this指向定義時的對象,也就是說箭頭函數一旦定義完成,它的指向是固定的,無法改變,它的指向是定義時所在的做用域,而不是執行時的做用域

2.不能夠當作構造函數

箭頭函數不能夠當作構造函數,也就是不能夠new一個,不然會報錯,以下:

var fn = ()=>{
        console.log("123");
    }
    new fn(); //Uncaught TypeError: fn is not a constructor

以上會報錯,由於箭頭函數自己沒有屬於本身的this,因此箭頭函數不能夠當作構造函數,也由於箭頭函數沒有本身的this,因此call()、apply()、bind()這些方法去改變this的指向對箭頭函數也是無效的,以下:

this.x = 'outer';
    (function() {
        console.log([
            (() => this.x).bind({ x: 'inner' })()
        ]);
    })();

輸出結果爲:

["outer"]

把箭頭函數經過bind綁定可見無效,箭頭函數仍是指向全局

以上是我的總結,有什麼不足之處歡迎留言探討!

相關文章
相關標籤/搜索