在ES6中容許使用 => 來定義函數,以下:javascript
var f = a => a; console.log(f(1)); //1
就等同於java
var f = function(a){ return a; } console.log(f(1)); //1
從上面能夠看出,在箭頭左側的是表明參數,若參數只有一個,()能夠省略,箭頭右側的表示函數代碼塊,若代碼塊裏面是個返回值,則{}能夠省略不寫app
若箭頭函數不須要參數,則左側用()代替,以下:函數
var f = () => { console.log("無參數狀況"); } f();//無參數狀況
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
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指向定義時的對象,也就是說箭頭函數一旦定義完成,它的指向是固定的,無法改變,它的指向是定義時所在的做用域,而不是執行時的做用域
箭頭函數不能夠當作構造函數,也就是不能夠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綁定可見無效,箭頭函數仍是指向全局
以上是我的總結,有什麼不足之處歡迎留言探討!