在阅读jQuery源码之前,先看下面这段简单的代码
(function(window){
var jQuery = function(select){
//返回jQuery对象
return new jQuery.fn.init(select);
}
jQuery.fn = jQuery.prototype = {
init:function(select){
this.selector = select;
},
selector:'',
getSelector:function(){
return this.selector.toLocaleUpperCase();
}
};
jQuery.fn.init.prototype = jQuery.fn;
window.$ = jQuery;
})(window);
为什么上面的一句return new jQuery.fn.init(select);可以返回jQuery对象呢?
我们知道,JavaScript创建对象有原型模式。这个模式大致是这样创建对象的:
var person = function(personName,personAge){
this.name = personName;
this.age = personAge;
};
person.prototype = {
getName: function(){
return this.name;
},
getAge: function(){
return this.age;
}
};
var p1 = new person('blackFez',23);
回到最开始的那段代码,里面的jQuery.fn.init就跟原型模式代码里面的person一样。由于有jQuery.fn.init.prototype = jQuery.fn; 所以,jQuery.fn.init的原型就是jQuery.fn,也就是jQuery.prototype。
所以,当new一个jQuery.fn.init对象后,这个对象里面有什么呢?它有init函数里面用到的selector属性,还有jQuery原型中的属性。
有了上面的讲解,现在再来看,当我们执行到$(‘#blackFez’)时,是怎么获取jQuery对象的呢。看下jQuery源码:
(function( window, undefined ) {
var
......
rquickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,
......
jQuery = function(selector, context){
//一切都从这里开始,使用原型模式创建jQuery对象
return new jQuery.fn.init( selector, context, rootjQuery );
},
.....;
jQuery.fn = jQuery.prototype = {
jquery: core_version,
constructor: jQuery,
init: function(selector, context, rootjQuery) {
var match, elem;
if (typeof selector === "string") { if (selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3) { ...... } else { match = rquickExpr.exec( selector ); } //在这里,我们传入的selector是'#blackFez' //所以得到的match是: //["#blackFez", undefined, "blackFez", index: 0, input: "#blackFez"] if ( match && (match[1] || !context) ) { if ( match[1] ) { ...... } else {//最终会执行这个if分支 elem = document.getElementById( match[2] ); if ( elem && elem.parentNode ) { if ( elem.id !== match[2] ) { return rootjQuery.find( selector ); } this.length = 1; this[0] = elem; } this.context = document; this.selector = selector; return this; } }else if(!context || context.jquery){ ...... }else{ ...... } }else{ ...... }
},
......
};
jQuery.fn.init.prototype = jQuery.fn;
......
window.jQuery = window.$ = jQuery;
上面贴的代码,是就是jquery的源码,很多我们这里不需要的代码,我用省略号表示。简化了代码后,我们会发现,跟我在文章最开始贴的那段代码是不是大同小异。主要的差别就是jQuery.fn.init这个函数。那jQuery源码在这个函数里面做了什么事呢?
当我们向这个函数传入’#blackFez’这个参数后,程序做了一些判断,最终会执行下面这段代码:
elem = document.getElementById( match[2] );
if ( elem && elem.parentNode ) {
if ( elem.id !== match[2] ) {
return rootjQuery.find( selector );
}
this.length = 1;
this[0] = elem;
}
this.context = document;
this.selector = selector;
return this;
可以看到,他会先获取id为blackFez的html元素,然后将这个元素赋给this[0],然后返回this。所以,最终得到的对象是一个:以jQuery.prototype为原型创建的对象,并且第一个属性是id为blackFez的html元素的对象。