2016-04-06 48 views
2

我相信(可能是我錯了)ECMA6中的方法定義使用箭頭函數(內部)並且必須保留「this」(上下文)。 但上下文「this」不保留在對象方法

class Foo { 
    methodOne() { 
     console.log("MethodOne is called") 
    } 

    methodTwo() { 
     console.log("MethodTwo is called"); 
     this.methodOne(); 
    } 
} 

var foo = new Foo(); 

var executing = function (someMethod) {someMethod()}; 

executing(foo.methodTwo) 

它會引發錯誤「遺漏的類型錯誤:無法讀取的未定義的屬性‘methodOne’(......)」

所以,無論是我的理解規格不正確或瀏覽器(Chrome,FF)和的NodeJS不支持這個呢?

+1

在規範它在哪裏這樣說_「使用箭頭功能(內部)」 _或_「‘本’(上下文)必須保持」 _?爲什麼它應該隨ES6而改變? – zeroflagL

+0

箭頭函數和方法定義是兩個不同的東西。 –

回答

3

ES6中的類只是語法上的糖而不是原型繼承。這樣,類中的方法聲明將附加到prototype對象。

1)該示例中的問題在於函數調用的方式。爲了保持上下文this,你仍然需要調用它作爲方法的對象上:

var foo = new Foo(); 

var executing = function (someMethod, context) {someMethod.apply(context)}; 

executing(foo.methodTwo, context); 

2)但是,如果你調用它爲常規功能,那麼你就必須以此爲undefined在嚴格模式:

methodTwo() { 
     console.log("MethodTwo is called"); 
     this.methodOne(); // <---- `this` is `undefined` 
} 

在函數調用this通過調用它的方式確定:

  1. 作爲常規功能(使thisundefined或非嚴格模式全局對象):someMethod();var m = foo.methodTwo; m();
  2. 作爲對象的方法(使this的對象):foo.methodTwo()
  3. 作爲構造(使得this新創建的對象):new Foo()
  4. 間接調用(使用apply(newContext)call(newContext)):someMethod.apply(context)

請注意,bound()方法可以在調用前修改上下文。它將取消對案例1,2和4調用的任何稍後的上下文修改。對於構造函數調用,綁定的上下文將被忽略並仍然使用新創建的對象。

檢查this nice post關於JavaScript中的函數上下文和調用。

+0

在後一種情況下,是不是全局對象而不是未定義? – RemcoGerlich

+1

@RemcoGerlich在嚴格模式中未定義,在非嚴格的全局對象中。 –

+0

@DmitriPavlutin如果你把它叫做'foo.method',你怎麼得到undefined? –

1

So, either I understood specification incorrect or browsers (Chrome, FF) and nodejs does not support this yet?

無論您閱讀規範的哪一部分,您都會誤解它。方法和箭頭函數是兩個不同的東西,即使方法有箭頭函數語義,也不會得到您期望的行爲(因爲箭頭函數從詞法上解析this)。

不,方法的工作方式與正常函數聲明/表達式一樣,爲this

又見How to access the correct `this` context inside a callback?

+0

你說得對。我再次閱讀了規範,對我來說變得很清楚。 – vmusulainen

相關問題