2012年1月16日 星期一

Javascript用prototype進行繼承會發生的奇怪現象



這問題真的很奇怪,而且很難理解。
測試網址如下(code很簡短,可直接看原始碼):
http://labs.medialand.com.tw/jason/html/inheritance/test1.html

狀況是,
1. 建立一個Test的類別,在建構子時宣告並初始化一個陣列testValue。
2. 在Test類別建立一個function addValue,用來將傳入的值push到testValue裡。
3. 在Test類別建立一個function destroy,用來將testValue清空。
4. 建立一個AA類別繼承Test類別。
5. 實體化一個AA類別,變數名稱a1,呼叫a1.addValue(123)將123這個值push到a1.testValue裡。
6. 呼叫a1.destroy()來清空a1.testValue。
7. 目前看起來都正常,怪的來了。
8. 實體化另外一個AA類別,變數名稱a2。
9. 直接取得a2.testValue,居然不是空值,而是123!!!
照道理說,testValue裡有123這個值,不管怎樣也是屬於a1這個instance的,不應該會出現在新new出來的instance裡。更何況在a1的時候已經執行過一次destroy來清掉testValue了。
無法理解。
這種情況目前測試,只發生在testValue非一般常數型態的變數上,數字跟字串不會發生這種情況,在array或object上就會發生這種異常的狀況。

解決方法應該有很多,目前我覺得我自己最喜歡的方式,就是在AA類別的建構子裡再一次強制呼叫父類別Test的建構子,就像AS3裡的super();一樣。
再測過一次後這個問題就會被解決。
修正過後的測試網址如下(差別只在於AA的建構子裡多了一行):
http://labs.medialand.com.tw/jason/html/inheritance/test2.html