看板 Ajax 關於我們 聯絡資訊
有一些書在講 inheritance 的時候會叫你這樣寫: function A(a) { this.a = a; } function B(b) { this.super_.apply(this, arguments); } B.prototype = new A; B.prototype.super_ = A; 然後 b1 = new B(1); b2 = new B(2); 會變成 b1.a === 1 && b2.a === 2 這種利用 parent constructor initiate 的方法不適用三層以上的繼承關係。 因為在 new 第三層的時候會丟出 RangeError: Maximum call stack size exceeded。 > -------------------------------------------------------------------------- < function A(a) { this.a = a; } function B(b) { this.super_.apply(this, arguments); } B.prototype = new A; B.prototype.super_ = A; function C(c) { this.super_.apply(this, arguments); } C.prototype = new B; C.prototype.super_ = B; 首先假設以上情境,然後 new C。 new C 的時候會進到 function C 的 context,在這個 context 裡面, this 已經是 instanceof C,所以 this.super_ 會 lookup C.prototype 的 super_, 也就是 this.super_ = B,到這裡都符合我們的預期。 this.super_.apply(this, arguments) 等同於 B.apply(this. argumets)。 B.apply(this. arguments),的時候會進到 function B 的 context, 在這個 context 裡面的 this 是 instanceof B 嗎?不,其實是 instanceof C。 因為我們用了 apply 把原本 instanceof C 的 this 帶進 function B 的 context。 然後在 function B 的 context 執行 this.super_.apply(this, arguments)。 剛剛說過在這個 context 的 this 是 instanceof C,而 instanceof C 的 super_ 則要 lookup C.prototype.super_ 也就是 B。所以這時候, 在 function B context 的 this.super_.apply(this, arguments) 等於 B.apply(this, arguments),回到上一段的開頭,變成一個無窮迴圈…… -- Oni devas ami animalojn. Ili estas tiel bongustaj. One should love animals. They are so tasty. 每個人都應該愛動物,他們是如此美味。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 175.180.52.96 ※ 編輯: B9 來自: 175.180.52.96 (12/20 00:39)
sk1765:你這個只要第三層繼承的人 不寫C.prototype.super_ = B; 12/21 16:16
sk1765:這一句就好了阿 http://jsfiddle.net/ZM2Hp/2/ 12/21 16:17
sk1765:還是我理解錯了 12/21 16:21
B9: 當然可以,可是 super 的用途本來就是用來 refer super class 12/21 19:59
B9: 只有第三層不寫的話,不然乾脆都不要寫 12/21 19:59