I am fasinated by the jQuery library. I do so much more with so less code. Here I try to mimic jQuery several features: chain operation, extentsion, constructor.
chain operation is pretty easy to mimic. We just need to add "return this;" to the end of a method. Here is my first try
var jQuery = function() {
}
jQuery.prototype =
{
version: "1.0",
showVersion: function() {
alert(this.version);
return this;
},
work: function() {
alert("work");
return this;
}
}
var j = new jQuery();
j.showVersion().work();
Extension is also simple. We just need to decorate its prototype like this
var jQuery = function() {
}
jQuery.prototype =
{
version: "1.0",
showVersion: function() {
alert(this.version);
return this;
},
work: function() {
alert("work");
return this;
}
}
var j = new jQuery();
j.showVersion().work();
jQuery.prototype.sleep = function() {
alert("sleep");
return this;
}
j.sleep();
The constructor is very tricky. First I need to create a jQuery object without "new" keyword. Can we just do this like the following?
var jQuery = function() {
return jQuery.prototype;
}
jQuery.prototype =
{
version: "1.0",
showVersion: function() {
alert(this.version);
return this;
},
work: function() {
alert("work");
return this;
}
}
var j = new jQuery();
j.showVersion().work(); //chain works
jQuery.prototype.sleep = function() {
alert("sleep");
return this;
}
j.sleep(); //extension works
j.version = "2.0";
j.showVersion();
jQuery().showVersion(); //we can create a jQuery object without new, but it show 2.0, it is a singleton.
It works. But seemly, there is a serious bug, that it returns a singleton. So I want to write the following naive code.
var jQuery = function() {
return new jQuery.prototype;
//jQuery.prototype is not a constructor
//return new jQuery.prototype();
//jQuery.prototype is not a constructor
}
It says, jQuery.prototype is not a constructor. so we need a constructor function to do the job.
var jQuery = function() {
return new jQueryConstructor();
}
jQuery.prototype =
{
version: "1.0",
showVersion: function() {
alert(this.version);
return this;
},
work: function() {
alert("work");
return this;
}
}
function jQueryConstructor() {
};
jQueryConstructor.prototype = jQuery.prototype;
//end of library
//following is test code.
var j = new jQuery();
j.showVersion().work(); //chain works
jQuery.prototype.sleep = function() {
alert("sleep");
return this;
}
j.sleep(); //extension works
j.version = "2.0";
j.showVersion();
jQuery().showVersion(); //it shows 1.0, it is not a singleton
Now everything works. But there is a potential that user may change the jQuery.prototype accidentally. let's add a reference jQuery.fn = jQuery.prototype, so that user focus on jQuery.fn, and let jQuery.prototype off attention. So I change the code like the following . Please note that the "return new jQueryConstructor()", you must use "new". Without "new", the prototype "jQueryConstructor.prototype = jQuery.fn" has no use. Here is an artical Create Advanced Web Applications With Object-Oriented Techniques more about the "new".
var jQuery = function() {
return new jQueryConstructor();
}
jQuery.fn = jQuery.prototype =
{
version: "1.0",
showVersion: function() {
alert(this.version);
return this;
},
work: function() {
alert("work");
return this;
}
}
function jQueryConstructor() {
};
//jQueryConstructor.prototype = jQuery.prototype;
jQueryConstructor.prototype = jQuery.fn;
var j = new jQuery();
j.showVersion().work(); //chain works
jQuery.fn.sleep = function() {
alert("sleep");
return this;
}
j.sleep(); //extension works
j.version = "2.0";
j.showVersion();
jQuery().showVersion(); //it shows 1.0, it is not a singleton
Can we make it more simple, yes, let's move the jQueryConstructor into the prototype.
var jQuery = function() {
return new jQuery.fn.init();
}
jQuery.fn = jQuery.prototype =
{
init: function() {},
version: "1.0",
showVersion: function() {
alert(this.version);
return this;
},
work: function() {
alert("work");
return this;
}
}
jQuery.fn.init.prototype = jQuery.fn;
var j = new jQuery();
j.showVersion().work(); //chain works
jQuery.fn.sleep = function() {
alert("sleep");
return this;
}
j.sleep(); //extension works
j.version = "2.0";
j.showVersion();
jQuery().showVersion(); //it shows 1.0, it is not a singleton
Done. I have skeleton of jQuery.
No comments:
Post a Comment