es6 箭頭函數

  • 函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。
    請看下面這個例子:
var a = {
    x: 'haha',
    f: () => {
        console.log(this.x);
    }
};
var b = {
    x: 'heiehi'
};
a.f(); // undefined
a.f.call(b); // undefined

輸出undefined是因為箭頭函數定義時所在對象為global對象,沒有x屬性(是在global對象的環境下定義的,即定義時this指向global,而不是a對象,這里容易混淆)。該函數在定義時,this就被綁定了定義時的所在對象。
再看一個例子:

function get() {
    return {
        f: () => {
            console.log(this.x);
        }       
    }
};
var b = {
    x: 'heiehi'
};
get.call(b).f(); // heihei
// 或
var b = {
    x: 'heiehi',
        get: function () {
            return {
                f: () => {
                    console.log(this.x);
                }       
            }
        }
};
b.get().f(); // heihei

這里get函數運行時的this指向b,f定義時this綁定了b。
PS: 在node中,運行一個js程序:

//test.js
function a() {
    console.log(this === global ? 'global' : this);
}
console.log(this); // {}
console.log(this === global); // false
a(); // global
a.call({x:1}); // {x:1}

可見與瀏覽器環境不同,全局環境下代碼執行時的this指向一個空對象,全局環境下調用函數,會將global對象傳給this。而在瀏覽器環境中(globalwindow對象),全局環境下的this即指向window

  • 不可以使用arguments對象,該對象在函數體內不存在。如果要用,可以用Rest參數代替。
    請看下面例子:
function a() {
    return () => {
        console.log(arguments);
    }
}
a(1,2,3)(5,6); // {'0':1,'1':2,'2':3}

箭頭函數內訪問arguments時,訪問的是外層代碼塊的arguments
再看一個例子:

//test.js
var a = 0;
// arguments = {};
setTimeout(() => {
    console.log(a);
    if (++a<10) {
        setTimeout(arguments.callee, 500);
    }
}, 500); // 1,1,1,1,1.................無限

在node環境中,上述代碼里的arguments.callee指向node運行test.js文件時,用來包裹代碼的函數。因此以上所有代碼就會不斷重復執行
在瀏覽器環境中,會報出arguments undefined的錯誤。因為瀏覽器運行js代碼不像node會包個函數在外面,所以箭頭函數中的代碼運行時,直接找外層代碼塊中的arguments,不在函數中所以就找不到了。
這時如果把arguments = {}這句去注釋,則不會報錯。看來箭頭函數運行時查找arguments也和查找普通變量一樣。

總結:

thisarguments在箭頭函數內的調用過程:箭頭函數運行時,引擎不定義這倆變量,這樣就會沿著作用域鏈向上查找,找到了箭頭函數定義時的thisarguments變量(這句話可能不嚴謹,還不了解js引擎,大概意思就是箭頭函數根本沒有自己的this,導致內部的this就是外層代碼塊的this)。
這也是為什么箭頭函數不能作為構造函數的原因。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容