jQuery源码解读之一代巨人“jQuery”
回忆一下,刚参加工作的时候就学了,js,jq。js本身就有兼容性的问题。比如获取样式,js里本身是有currentStyle和getComputedStyle两种方法。ie,支持document.getElementById("button").currentStyle;而高级浏览器是没有这个的,高级浏览器,支持window.getComputedStyle;那么jq的出现让我们不用关心这个问题了。因此,在工作中我们从来都是集中精力处理css的兼容问题,很少处理js的兼容问题。
随着互联网的发展,技术不断革新,很多常用功能被内置到语言本身。我们不再需要jq库来给我们做shim,来解决。时至今日,巨人jq开始慢慢衰退,开始淡出舞台。虽然,旧的实物必将淘汰,但是jq里面还是有很多智慧在里面。这个是值得我们去深挖的。讲之前,我们有必要知道一下他的作者,作者是谁?查了下,感谢John Resig(约翰.瑞森);
废话说完了,我们从设计的角度开始分析:jq使用起来很简单,他的方法通常是 .ajax;so easy!正是因为这样,我们更多的人才愿意用他。然后这是个不小的工程查了一下,JavaScript Library v3.3.1,有10368行代码。这代码量相当多。这么多代码,管理起来,我们需要仔细思考。要避免写多余代码,要分类管理。重复的代码肯定不要写了,这时作者选择了,继承。javascript的继承是通过proto原型链实现的,如果我们要实现怎么去实现呢。首先我们必须让$(),返回的是对象,这样才有后面的链式调用,继承。如下demo
demo1
(function(root){
var jQuery = function(){
return new jQuery();
}
root.$ = root.jQuery;
})(window);
$();//Uncaught RangeError: Maximum call stack size exceeded
报错了,这个错误很有意义。我们是想通过$(),返回一个jq对象实例。$(),调用了函数jQuery 。函数jQuery,返回了jQuery的实例,这个时候,$()函数调用;内部返回new jQuery();他在自己调用自己。so,报了个错,超出最大内存限制。显然,我们想通过$(),返回实例。但是这样做是行不通的。
返回一个实例,而且不能指向自己,但是能从自己实例上搜索到方法。这就是我们要达到的目的,也是我们要解决的。
上帝视角:
(function(root){
var jQuery = function(){
return new jQuery.prototype.init();
}
jQuery.prototype = {
init:function(){
}
}
root.$ = root.jQuery;
})(window);
$()
这里为$()找到了一个新的构造函数jQuery.prototype.init,解决了报错。然后就可以开始写代码了。
image.png这么多的代码,需要一个代码管理工具。我们来看看,源码里出现频率比较高的,extend。jquery需要管理两大方法,属性方法,和实例方法,分别举例$.ajax(),$().css();这个都是通过extend来管理。
var obj = {name:"dwq"}
var result = {age:29};
//给任意对象扩展
$.extend(obj,result);
console.log(obj);
//jQuery本身扩展
$.extend({
work:function(){
console.log("hello!");
}
});
//jQuery实例对象扩展
$.fn.extend({
css1:function(){
console.log("css1");
}
});