2015-11-15 95 views
1

traverse NPM包有這個例子如何更改ES6箭頭函數的「this」指向的內容?

var obj = [ 5, 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ]; 

traverse(obj).forEach(function (x) { 
    if (x < 0) this.update(x + 128); 
}); 

裏面的回調函數可以調用this.update。我知道在這種情況下,您應該使用常規(不是ES6箭頭)風格的函數定義,如上所示。

但出於好奇,你會如何使用ES6的箭頭函數語法的代碼工作?如果我嘗試如下,我得到TypeError: Cannot read property 'update' of undefined,因爲當然this是不一樣的上面。

traverse(obj).forEach((x) => { 
    if (x < 0) this.update(x + 128); 
}); 

我嘗試用bind改變this,但沒有成功。如何在ES6箭頭功能中更改this

回答

6

如何在ES6箭頭功能中更改this

你不能,這是使用箭頭函數(除了簡潔的語法)的全部要點。如果您需要控制this,請勿使用箭頭功能。

1

ES6中的箭頭函數有lexical this。這意味着您可以通過詢問「定義函數時this的值是多少」來始終告訴他們的this - 值?它們不受this調用,應用,綁定和方法調用的影響。

讓我們來看看預期的效果,編寫ES6到ES5 Babel

ES6:

let foo = { 
    bar() { 
    return [ 
    () => this, 
     function() { 
     return this 
     } 
    ] 
    }, 
    baz:() => this 
} 

let fns = foo.bar() 
fns.push(...fns.map((fn, i) => fn.bind({i}))) 
fns.map(fn => fn()).forEach(thisVal => { 
    console.log(thisVal) 
    console.log('-------') 
}) 
console.log(foo.baz()) 

編譯到ES5:

'use strict'; 

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } 

var foo = { 
    bar: function bar() { 
    var _this = this; 

    return [function() { 
     return _this; 
    }, function() { 
     return this; 
    }]; 
    }, 

    baz: function baz() { 
    return undefined; 
    } 
}; 

var fns = foo.bar(); 
fns.push.apply(fns, _toConsumableArray(fns.map(function (fn, i) { 
    return fn.bind({ i: i }); 
}))); 
fns.map(function (fn) { 
    return fn(); 
}).forEach(function (thisVal) { 
    console.log(thisVal); 
    console.log('-------'); 
}); 
console.log(foo.baz()); 

檢查內部foo.bar發生了什麼事。有一個插線:

var _this = this; 

箭頭功能的屍體被更改,以便它從詞法外部範圍返回_this。因此,綁定this的值不應該有任何影響。通過在函數定義之前「凍結」this的值,我們阻止了通過綁定,使用call/apply或將函數作爲方法調用來改變函數行爲的能力。

請注意如何將baz的此值替換爲undefined。這是因爲如果我們問「功能定義時this的值是多少」,我們顯然必須回答undefined或某個全局對象上下文,如節點的global或瀏覽器的window。通過詢問這個問題,你可以很容易地推出箭頭函數內部的價值this,這是它們固有價值的重要組成部分。因此

的輸出是:

{ bar: [Function: bar], baz: [Function: baz] } 
------- 
undefined 
------- 
{ bar: [Function: bar], baz: [Function: baz] } 
------- 
{ i: 1 } 
------- 
undefined 

第一和第三輸出對應於內bar()定義的箭頭功能。請注意,它們自動具有this - 指向由foo引用的對象的值,因爲它們是使用foo.bar()調用創建的。有用的權利?只有非箭頭功能的行爲可以通過綁定進行更改。在綁定之前,它的值爲this - 值爲undefined,這是導致函數傳遞時JS錯誤和冗餘綁定的常見原因。箭頭功能帶走了很多麻煩。

相關問題