2016-03-06 84 views
2

我知道(我認爲)ES6中的箭頭功能使用Lexical this,但我不確定爲什麼fat arrow功能調用的函數將this設置爲undefined。如何在由ES6箭頭函數調用的函數中使用`this`?

我需要做些什麼才能撥打this.setResulthandleAuthResult?如果我不需要,我不想使用舊的function() {}.bind(this)

"use strict"; 

class Example { 
    constructor() { 
     this.checkAuth(); 
    } 

    checkAuth() { 
     document.write("Checking auth now. "); 
     var iid = setInterval(() = > { 
      if (true) { // Have to do some dumb check here 
       clearInterval(iid); 
       this.authenticate(this.handleAuthResult) 
      } 
     }, 500); 
    } 

    authenticate(callback) { 
     callback({ 
      value: true 
     }); 
    } 

    handleAuthResult(result) { 
     document.write(`The result is ${result.value}.`); 
     this.setResult(result, this.loadThePage) 
     //^`this` is undefined here. How can I ever set the result? 
    } 

    // Another asynchronous thing 
    setResult(result, callback) { 
     callback(); 
    } 

    loadThePage() { 
     document.write("The code never gets here, but the page should load now. "); 
    } 
}; 
var example = new Example(); 

謝謝! https://jsfiddle.net/vujev4dj/

編輯:在我的這種防禦被標記爲重複的行爲我期待做下面小提琴,這就是爲什麼我預計不會有ES6使用bind功能上this.handleAuthResult工作: https://jsfiddle.net/m9e7j4ds/

+0

它在撥弄工作的原因是因爲它使用'React.createClass()',而不是使用ES6類(延伸'React.Component') 。 'React.createClass()'綁定所有方法,這在使用ES6類時不會發生。 – ArneHugo

+0

@bergi我不同意這是你鏈接的問題的重複,因爲它不是將方法綁定到ES6類實例的方法。尤其是,在答案中沒有提及直接製作一個箭頭功能。我相信這是提問者正在尋找的東西,儘管問題可能會更好地提出。 – ArneHugo

回答

0

this是在handleAuthResultundefined因爲handleAuthResult不是箭頭功能,因此不具有詞法this。這是一個正常的原型函數(鬆散地,「方法」),這意味着this是由它的調用方式定義的。

你調用它的方式:

authenticate(callback) { 
    callback({ 
     value: true 
    }); 
} 

不設置this具體的東西,所以thisundefined(因爲你在嚴格模式下是)。

爲了解決這個問題,必須通過thisauthenticate,並使用它:

this.authenticate(this.handleAuthResult, this) 

authenticate(callback, thisArg) { 
    callback.call(thisArg, { 
     value: true 
    }); 
} 

或使用Function#bind創建,調用它時,會調用handleAuthResult用正確的函數this

this.authenticate(this.handleAuthResult.bind(this)) 

或出於完整性考慮,naomik points out a third option which is quite elegant:使用另一個箭頭功能:

this.authenticate(() => this.handleAuthRequest()) 
+1

我看到你也在這裏附加@ naomik的解決方案。你的回答總體上非常簡潔,解釋了我爲什麼感到困惑。我接受了你的回答:) –

0

checkAuth,你應該使用

this.authenticate(this.handleAuthResult.bind(this))

這是因爲,當CA灌裝callback({value: true});有沒有this綁定

+0

另一種方法是將回調方法定義爲箭頭函數,當應用於類時,它們總是與它們所在的類綁定。這個問題具體詢問有關箭頭功能。 – ArneHugo

4

當你調用

this.authenticate(this.handleAuthRequest); 

this變得失去

你可以做

this.authenticate(this.handleAuthRequest.bind(this)); 

或者

this.authenticate(() => this.handleAuthRequest()); 

總的來說,代碼非常凌亂,很多部分對我來說沒有任何意義。具體callback({value: true})是很奇怪的。無論如何,如果您有更具體的問題,我很樂意提供幫助。

+1

關於使用另一個箭頭功能的第三個選項的好處。 –

+0

非常感謝您的建議。我同意代碼很混亂,但它實際上是Google提供的這個JavaScript快速入門的超級簡化版本,我用我自己的函數替換了它們的函數,並使用了回調函數:https://developers.google.com/google-apps/calendar/quickstart/js#step_1_turn_on_the_api_name –

+1

謝謝@TJ。我通常更喜歡使用另一個箭頭函數,而不是靠'Function.prototype.bind' – naomik

相關問題