无 new 构造
最简单的想法
(function(window) {
var jQuery = function() {
return new _jQuery();
};
var _jQuery = function() {};
window.jQuery = window.$ = jQuery;
})(window);
这个实现挺好的,能达到无 new 构造的要求,不过并不利于扩展,比如下面这段代码:
jQuery.prototype.test = function() {
console.log("test");
};
在原版 jQuery 下是这样的结果:
在我这个简化山寨版下是这样:
小小改动
(function(window) {
var jQuery = function() {
return new jQuery();
};
window.jQuery = window.$ = jQuery;
})(window);
彻底歇菜,死循环了:
this 的指向
这段代码是我打瞌睡的时候写的,真照着 jQuery 源码来写是写不出来的:
(function(window) {
var jQuery = function() {
return jQuery.prototype.init();
};
jQuery.prototype.init = function() {
return this;
};
window.jQuery = window.$ = jQuery;
})(window);
跑上面的测试都没有问题,非常完美,最起码我开始写出来的时候是这么认为的,不过我又写了段测试,就发现问题了:
$() === $();
结果竟然是 true!
$() === $.prototype;
再看这个,结果也是 true,就明白是为什么了,同时 this 指向也搞清楚了,指向的是 jQuery.prototype。
new 起来
(function(window) {
var jQuery = function() {
return new jQuery.prototype.init();
};
jQuery.prototype.init = function() {};
window.jQuery = window.$ = jQuery;
})(window);
还存在一个问题就是,返回的是 jQuery.prototype.init 的一个实例,jQuery 原型上的方法一个都访问不了。
原型链修复
(function(window) {
var jQuery = function() {
return new jQuery.prototype.init();
};
jQuery.prototype.init = function() {};
jQuery.prototype.init.prototype = jQuery.prototype;
window.jQuery = window.$ = jQuery;
})(window);
链式调用
这个看起来高大上,实现起来其实很简单,每个方法返回 this 就行了:
(function(window) {
var jQuery = function() {
return new jQuery.prototype.init();
};
jQuery.prototype.init = function() {};
jQuery.prototype.init.prototype = jQuery.prototype;
jQuery.prototype.test = function() {
return this;
}
window.jQuery = window.$ = jQuery;
})(window);
代码地址
https://github.com/oldmanscode/jq_step_by_step/blob/master/step2.js