JavaScript模擬Java類繼承
javascript采用原型繼承的方式繼承一個類,但一些使用過Java的程序員可能習慣使用經典的類繼承,但javascript原生并不支持這種方式,因此需要手動實現。我是通過定義一個定義類的函數實現的,由于javascript沒有訪問修飾符,因此如果需要使用到private成員,請使用閉包。
/將一個對象的自有屬性復制到另一個對象的方法/
function merge(from, to){
for(var i in from){
if(from.hasOwnProperty(i)){
to[i] = from[i];
}
}
}
/*用于定義一個類
*參數:構造函數,繼承的父類, 屬性, 靜態屬性, 是否為單例模式
*注意:單例模式下返回非原始構造函數
*/
function defineClass(constructor, parent, properties, statics, isSingleton){
/*如果為單例模式,保存實例,并在以后的調用中返回此實例*/
if(isSingleton){
var instance, oldConstructor = constructor;
constructor = function(){
if(instance) return instance;
oldConstructor.apply(this, arguments);
instance = this;
}
}
/*設置原型屬性,這意味著傳入的構造函數的原型屬性將被覆蓋
*javascript沒有函數重載,因此parent函數需要做一些特殊處理,詳情見parent定義
*/
constructor.prototype = new parent();
/*將自有屬性復制到原型中
*將靜態屬性復制到構造函數中,這意味著將不會繼承parent的靜態屬性
*/
merge(properties, constructor.prototype);
merge(statics, constructor);
/*將構造函數更改為當前構造函數
*將parent的引用保留
*/
constructor.prototype.constructor = constructor;
constructor.prototype.parent = parent;
return constructor;
}
function parent(){
/*可以將這里看成兩個構造函數,一個在定義子類時使用的無參構造函數,一個有參構造函數
*如果子類需要參數來使用父類初始化,可以通過this.parent得到
*/
this.name = "parent";
if(arguments.length){
log(this.name + "'s constructor with params");
}
}
var child = defineClass(function(){
//this.parent.apply(this, arguments);
this.name = "child";
if(arguments.length){
log(this.name + "'s constructor with params");
}
}, parent, {
say: function(){
log(this.name);
}
}, {
value: "static"
}, true);
var instance = new child(), instance2 = new child();
log(child.value); //static
log(instance.name); //child
instance.say(); //child
log(instance === instance2); //true
log(instance instanceof parent) //true
/*可以在child基礎上擴展
*/
var grandSon = defineClass(function(name){
this.name = "grandSon";
if(arguments.length){
log(this.name + "'s constructor with params");
}
}, child, {
shout: function(){
log("shout: " + this.name);
}
});
var instance3 = new grandSon();
instance3.say(); //grandSon
instance3.shout(); //shout: grandSon
log(instance3 instanceof child); //true
log(instance3 instanceof parent); //true
/*打印日志*/
function log(msg){
if(window.console){
console.log(msg);
}
}</pre>
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!