Created
February 13, 2012 16:12
-
-
Save winsonwq/1817919 to your computer and use it in GitHub Desktop.
JavaScript Inheritance (not 100% perfect)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
why is it not 100% perfect? | |
- because if you wanna override the parent's method to get the private variable and use | |
my way to extend, you can not get the right value. in this code, a example can be found | |
to demonstrate the right way to use extend method, in this example, is you change the 'title' | |
variable like this way 'var title' not 'this.title', finally you just get the undefined value | |
after invoking the getTitle on Child class instance. | |
- any question, contact me through http://sheldonw.sinaapp.com | |
*/ | |
function extend(child, parent){ | |
var temp = function(){}; | |
temp.prototype = new parent; | |
child.prototype = new temp; | |
/* | |
why we need constructor | |
- if not, the child instance's constructor will be parent. | |
*/ | |
child.prototype.constructor = child; | |
child.__super__ = temp.prototype; | |
child.Base = function(){ | |
parent.apply(this, arguments); | |
/* | |
why we need delete property in this object | |
- because after invoking "child.__super__.constructor.apply(this, arguments);", | |
there may be some privilege method extended on this object, but if the child | |
class have the overrided method using the same name in its prototype definition, | |
we must delete the property on this object so that the property with the same name | |
will work. | |
*/ | |
for(var p in this){ | |
var inPrototype = child.prototype.hasOwnProperty(p); | |
var inThis = this.hasOwnProperty(p); | |
if(inPrototype && inThis){ | |
delete this[p]; | |
} | |
} | |
}; | |
// static methods | |
for(var p in Parent){ | |
if(parent.hasOwnProperty(p)){ | |
child[p] = parent[p]; | |
} | |
} | |
} | |
/* Parent class definition */ | |
function Parent(title){ | |
this.title = title; | |
function privateMethod(){ | |
return 'parent\'s private method.'; | |
} | |
this.privilegeMethod = function(){ | |
return 'parent\'s privilege method.'; | |
}; | |
this.getTitle = function(){ | |
return this.title; | |
} | |
} | |
Parent.staticMethod = function(){ | |
return 'parent\'s staticMethod.'; | |
} | |
Parent.prototype.publicMethod = function(){ | |
return 'title : ' + this.getTitle() ; | |
}; | |
/* Child class definition */ | |
function Child(title, subTitle){ | |
Child.Base.call(this, title); | |
this.subTitle = subTitle; | |
this.publicMethod = function(arg0){ | |
return [arg0 + ':' + Child.__super__.publicMethod.apply(this), 'subTitle : ' + this.getSubTitle()].join(' + '); | |
}; | |
this.getSubTitle = function(){ | |
return this.subTitle; | |
}; | |
this.getTitle = function(){ | |
return Child.__super__.getTitle.call(this) + ' from child.'; | |
}; | |
} | |
// call after child definition | |
extend(Child, Parent); | |
Child.childStaticMethod = function(){ | |
return 'child\'s childStaticMethod.'; | |
}; | |
Child.prototype.childPublicMethod = function(){ | |
return 'child\'s childPublicMethod. ' + [this.getTitle(), this.getSubTitle()].join(' '); | |
}; | |
Child.prototype.privilegeMethod = function(){ | |
return 'child\'s privilegeMethod'; | |
}; | |
var parent = new Parent('parent title'); | |
var child = new Child('child title', 'child subTitle'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment