ES6中新增了箭頭函數這種語法,箭頭函數以其簡潔性和方便獲取this的特性。下面來總結一下他們之間的區別:
普通函數下的this:
- 在普通函數中的this總是代表它的直接調用者,在默認情況下,this指的是window,
- 在嚴格模式下,沒有直接調用者的函數中的this是 undefined使用
- call,apply,bind(ES5新增)綁定的,this指的是 綁定的對象
箭頭函數中的this:
- 箭頭函數沒有自己的this, 它的this是繼承而來; 默認指向在定義它時所處的對象(宿主對象),
- 而不是執行時的對象, 定義它的時候,可能環境是window,也有可能是其他的。
看下面這段代碼:
function a() { console.log(this); //window } a();
因為a是一個全局函數,也就是掛載在window對象下的,所以a(),等價於window.a();
var obj = { say: function () { setTimeout(function () { console.log(this); //window }); } } obj.say();
定時器中的函數,由於沒有默認的宿主對象,所以this指向window
var obj = { func: function() {}, say: function () { console.log(this);//obj,此時的this是obj對象 setTimeout(function () { console.log(this); //window that.func(); }); } } obj.say();
此時say的宿主環境是obj,所以say里面的this是obj,定時器中的函數, 由於沒有默認的宿主對象,所以默認this指向window
嚴格模式下的this:
function test() { 'use strict'; console.log(this); //undefined } test();
在嚴格模式下,沒有直接調用者的函數中的this是 undefined
"use strict"; var obj={ say:function(){ console.log(this); //obj } }; obj.say();
有直接調用者的this是它的調用者
箭頭函數中的this:
var obj = { say: function () { setTimeout(() => { console.log(this);// obj }); } } obj.say();
此時的 this繼承自obj, 指的是定義它的對象obj, 而不是 window!
var obj = { say: function () { var f1 = () => { console.log(this); // obj setTimeout(() => { console.log(this); // obj }) } f1(); } } obj.say()
因為f1定義時所處的函數 中的 this是指的 obj, setTimeout中的箭頭函數this繼承自f1,所以不管有多層嵌套,都是 obj
var obj = { say: function () { var f1 = function () { console.log(this); // window, f1調用時,沒有宿主對象,默認是window setTimeout(() => { console.log(this); // window }) }; f1(); } } obj.say()
結果: 都是 window,因為 箭頭函數在定義的時候它所處的環境相當於是window, 所以在箭頭函數內部的this函數window