I made a my version of the John Resig's JavaScript Inheritance solution. The main difference is that my one doesn't impose that every 'class' have to inherit a single ancestor. This is important if you wont to inherit an already existent 'class' that is not defined in same manner.
This would be possible too:
this.name = name;
}
Person.prototype.presentYourself = function() {
return "Hi. I am " + this.name + ".";
}
var Employee = $class(Person, {
constructor: function(name, profession) {
this._super(name);
this.profession = profession;
},
presentYourself: function() {
return this._super() +
" I am a " + this.profession;
},
offerHelp: function() {
return "Can I help you?";
}
});
Other notable difference is that constructor is used instead of init. This is because in JavaScript the constructor property is already intended to contain the prototype constructor. Also the usage of init would not be safe if the super class like Person would use it with other meaning then constructor.
Usages of the $class function can be explained with this code:
var SubClass = $class(MyClass, { /* properties */ });
There is also an $object function to inherit objects (great for singletons):
var chaotic_universe = $object(universe, { /* properties */ });
jQuery plugin Inheritance
JavaScript is primarily a prototype-based language, and to extend jQuery with plugins, we uses prototype-based paradigm. However, it is well-known that JavaScript can be used also for prototype-oriented and even object-oriented programming (where 'oriented' stays for inheritance).
Also are actual issues about an more advanced jQuery plugin system, where plugins are entities associated to DOM elements (such as widgets). In my opinion, this is great opportunity to introduce more powerful programming paradigms to jQuery and to use them within plugins.
Here is an my try: jquery.plugin.js.
Here are some usage examples:
init: function() {
this.$el.addClass( this._opt.className );
},
destroy: function() {
this.$el.removeClass( this._opt.className );
return this._super();
},
getElement: function() {
return this.el;
}
})
.setOptions({
className: "my_plugins"
})
.extend({
salute: function() {
alert( "Hi! I am plugin " + this._name_ + "!" );
}
});
$.plugin('myPlugin2', $.myPlugin, {
init: function() {
this._super();
if ( this._opt.hidden ) {
this.$el.hide();
}
}
})
.setOptions({
hidden: true
});
$.myPlugin.salute(); // => "Hi! I am plugin myPlugin!"
$.myPlugin2.salute(); // => "Hi! I am plugin myPlugin2!"
$('a').myPlugin();
$('a').myPlugin('getElement') === $('a')[0]; // => true
$('p').myPlugin2({hidden: false});
$('p').hasClass('my_plugins'); // => true
$('p').myPlugin2('destroy').hasClass('my_plugins'); // => false
Some things I would to note about this solution:
$.plugin.base.$.plugin.baseinherits$.base, a generic base class.this._super()(inspired by John Resig)./^_.*_$/are considered special and read-only._options_that defines default options. The static methodsetOptionsis used to set changes.Ainherits pluginB, thenA._options_inheritsB._options_.Once a plugin is instantiated, its instance contains:
el) and respective jQuery object ($el)._opt.Object Oriented Programming
There are several benefits by adopting such OOP to plugins. Here are some:
extendedandextend).Although
$.plugin()would handle plugin creations and all its OOP and jQuery stuff, it can be useful to define non-plugin classes too. For that purposes the base class is exposed to be easily extended:init: function(name) {
this.name = name;
},
presentYourself: function() {
return "Hi. I am " + this.name + ".";
}
});
var Employee = Person.extended({
init: function(name, profession) {
this._super(name);
this.profession = profession;
},
presentYourself: function() {
return this._super() + " I am a " + this.profession + ".";
},
offerHelp: function() {
return "Can I help you?";
}
})
.extend({
fromPerson: function(person, profession) {
profession = profession || "recruit";
return this.create( person.name, profession );
}
});
var p = Person.create("Robert");
p.presentYourself(); // => "Hi. I am Robert."
var e = Employee.fromPerson(p);
e.presentYourself(); // => "Hi. I am Robert. I am a recruit."
e.offerHelp(); // => "Can I help you?"