1.1.
繼承
今天遇到了需要在
javascript
中繼承的問題:
查了一些帖子,自己又寫了幾個例子測試了一下,總結如下:
1.1.1.
???
三種方法
js
中實現繼承有三種方法:
假設父類為
Parent,
子類為
Child,
?
第一種,子類強制調用父類構造
function Child(){
?????? Parent.call(this);
}
?
第二種,子類間接調用父類構造
function Child(){
?????? this.base = Parent;
?????? this.base();
}
?
第三種:設置原型
function Child(){}
Child.prototype = new Parent();
這種方式雖然不夠直觀,卻應該是最有效率的方式。
?
1.1.2.
???
總結:
其實
js
本身是沒有什么繼承之類的概念的,只是為了使用利用
js
的一些特性而加的。
?
js
的原型方式
prototype,
使得許多的工作變得容易。
?
一個
function
對象和根據
function
構造出來的對象是不同的。
?
一個
function
對象的原型其實就是一個根據
function
對象構建出來的對象。
記住:這個對象可與
new
出來的對象不一樣。在
function
內部的代碼并不會被執行,如:
this.funcName = function()
這樣的代碼。而
new
出來的對象則不然,他具有執行后的對象特性。
?
function
的局部變量相當于
class
里的私有變量,無法在子類中獲取和操作。但
this.
的部分是可以的。
?
1.1.3.
???
猜測和假想
(這是我推斷的,沒有任何的根據,當然也是可以測試的):
當一個
Child
被
new
時,第一二種方法中,
js
執行器
1
、先分配一個空間,(相當于
this = new Object()
)
(msdn
中有具體的描述
)
2
、拷貝原型:
3
、執行構造:也就是
Child.call(this)
(相當于
child(),
此時
this
對象有值)(
msdn
中有描述)
然后執行
Parent();
這個時候
parent
的構造函數執行以下幾步:
1
、將
parent
的
prototype
拷貝到
object
區域,這時覆蓋了前面的區域
(
好像測試證明
parent
的原型并不會被拷貝,此步不會被執行
)
2
、對這個區域執行初始化,也就是正常的
function
調用的過程。(相當于
Parent(),this
變量有值)
?
而普通的
function
調用應該是這個樣子:由于沒有
new
操作符,所以沒有為其分配當前的
this(
也沒有空間
),
this
被放到了
window
對象上。但是
new
的時候顯然不是這樣。
?
obj.func()
的調用和
func()
調用是完全不一樣的,
obj.func
中
this
對象是
obj
對象,而
func()
調用
this
對象是
window
對象,這個應該和
jvm
中靜態方法和類實例方法調用的區別的原理一樣。
?
1.2.
方法重載
在實現了對象繼承之后,我開始面臨到第二個問題,重載。
1.1.4.
???
兩種方法
js
怎樣實現重載。
1
、簡單的重載:
在這種重載中,子類的方法無需調用父類的方法,直接在執行父類構造之后,再執行子類的重載方法,如
Parent
的
toString()
方法,這時只需執行
this.toString = function(){....}
就可以了。
?
2
、調用父類方法的重載:
由于
js
實際運行時并沒有父類、子類兩個實例空間,所以
super.toString()
肯定是不行的,而在子類的
toString
方法中進行
this.toString()
調用只能引起內存溢出,其實這種也可以想辦法做到。
?
this.super_toString = this.toString();
this.toString=function(){
?????? ..............
?????? this.super_toString();
?????? ..............
}