Skip to content

Instantly share code, notes, and snippets.

@winsonwq
Created February 13, 2012 16:12
Show Gist options
  • Save winsonwq/1817919 to your computer and use it in GitHub Desktop.
Save winsonwq/1817919 to your computer and use it in GitHub Desktop.
JavaScript Inheritance (not 100% perfect)
/*
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