2017-10-22 72 views
0

考慮以下超類和子類擴展它:ES6箭頭功能觸發「‘超級’的函數或類外」錯誤

class SuperClass { 
    constructor(name){ 
     this.name = name; 
    } 

    sayName =() => { 
     alert(this.name); 
    } 
} 

class SubClass extends SuperClass { 
    constructor(name){ 
     super(name); 
    } 

    sayName =() => { 
     super.sayName(); 
     document.getElementsByTagName('body')[0].innerHTML = this.name; 
    } 
} 

let B = new SubClass('Noam Chomsky'); 
B.sayName(); 

在該例子中,函數sayName被寫爲在兩個箭頭功能類定義。當我打電話B.sayName()我得到一個錯誤說:

'super' outside of function or class

JSFiddle demonstrating the error(檢查控制檯)


不過,如果我重新寫的類定義不使用箭頭功能,一切工作正常我沒有得到一個錯誤:

class SuperClass { 
    constructor(name){ 
     this.name = name; 
    } 

    sayName() { 
     alert(this.name); 
    } 
} 

class SubClass extends SuperClass { 
    constructor(name){ 
     super(name); 
    } 

    sayName() { 
     super.sayName(); 
     document.getElementsByTagName('body')[0].innerHTML = this.name; 
    } 
} 

let B = new SubClass('Noam Chomsky'); 
B.sayName(); 

JSFiddle demonstrating that it works fine

有人可以解釋爲什麼我在這裏使用箭頭函數時出現這個錯誤嗎?

+0

爲什麼要定義'sayName'作爲首位箭頭的功能? 'sayName =()=> {alert(this.name); }語法甚至還沒有標準(目前是第2階段) –

+2

jsfiddle使用的Babel版本可能存在問題。正如其中一個答案所說的,調用'super.sayName()'不管用,因爲'SuperClass.prototype'上沒有'sayName'方法。 **然而**,在SubClass的'sayName'方法內引用'super'應該可以工作。畢竟,代碼是一樣的(注意,我在'SuperClass'中使'sayName'成爲一個合適的方法):https://jsfiddle.net/5y9bqwd0/ –

+0

這裏是另一個子箭頭函數屬性的選項:https: //jsfiddle.net/zoeh5bp2/。他們的Bot是關於從構造函數中關閉'super'的。 – dhilt

回答

2

所不同的是

sayName1 =() => { 
    alert(this.name); 
} 

是具有功能類型的屬性,而

sayName2() { 
    alert(this.name); 
} 

是一種方法。 ES類以完全不同的方式處理方法和屬性。方法存在於類原型上,而屬性被分配給每個實例。並且您不能通過super.sayName1訪問父母的sayName1,這是因爲它不在您父母的班級,它只在實例對象上,並且可以通過instance.sayName1訪問。

此外,從ECMAScript® 2015 Language Specification

An ArrowFunction does not define local bindings for arguments, super, this, or new.target. Any reference to arguments, super, this, or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment... An ArrowFunction that references super is always contained within a non-ArrowFunction and the necessary state to implement super is accessible via the scope that is captured by the function object of the ArrowFunction.

+1

*「您不能通過'super.sayName1'訪問父母的'sayName1',因爲它不在您父母的班級上」*這是正確的,但這會導致不同的錯誤。看來OP甚至不能在箭頭函數內引用'super',但它應該可以工作IMO,因爲它只是用於在構造函數內分配函數的語法糖。 –

+0

我打算接受這個答案,因爲它解釋了爲什麼不應該在這裏使用箭頭函數,儘管我的具體錯誤看起來是由Babel中的一個錯誤引起的(請參閱上面的註釋)。 – o01

1

就我所知,在大多數情況下,箭頭函數的作用就像常規函數一樣。但是,當您處理「this」關鍵字會發揮作用的實例時,箭頭函數會將「this」綁定到定義它的上下文。如果你使用常規功能,你應該沒有問題。

+0

嘗試console.log(this);在superClass和subClass中,你會看到我的意思 –

+1

這與OP的問題有什麼關係? –