jquery 源码分析-核心(1)初始化init
jquery是目前用的最多的js框架,决定好好研究下它的源码,选取的是1.2.5版本,这是我在网上能找到的最早版本,我想jquery的核心思想在最开始的版本就表现了出来的,2.x以后的版本主要是加新功能,看源码主要就是理解它的编码思想,这个版本够用。
jquery初始化
在页面引入jquery的包就能用,$(),JQuery(),这是为什么?源码的开头就解决了这个疑惑
(function(){
// Map over jQuery in case of overwrite
var _jQuery = window.jQuery,
// Map over the $ in case of overwrite
_$ = window.$;
var jQuery = window.jQuery = window.$ = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context );
};
````````````````````````````````
})()
jquery整个都是包裹在一个匿名函数(function(){})()中,匿名函数的好处就是立即执行,变量不会被污染;
var jQuery = window.jQuery = window.$
说明整个jquery是绑定到window全局对象上的,就和alert函数一样,这样我们才能直接用$,jQuery这些特殊符号,接下来看jQuery.fn.init方法
jQuery.fn = jQuery.prototype = {
init: function( selector, context ) {
// Make sure that a selection was provided
selector = selector || document;
// Handle $(DOMElement)
if ( selector.nodeType ) {
this[0] = selector;
this.length = 1;
return this;
}
// Handle HTML strings
if ( typeof selector == "string" ) {
// Are we dealing with HTML string or an ID?
var match = quickExpr.exec( selector );
// Verify a match, and that no context was specified for #id
if ( match && (match[1] || !context) ) {
// HANDLE: $(html) -> $(array)
if ( match[1] )
selector = jQuery.clean( [ match[1] ], context );
// HANDLE: $("#id")
else {
var elem = document.getElementById( match[3] );
// Make sure an element was located
if ( elem ){
// Handle the case where IE and Opera return items
// by name instead of ID
if ( elem.id != match[3] )
return jQuery().find( selector );
// Otherwise, we inject the element directly into the jQuery object
return jQuery( elem );
}
selector = [];
}
// HANDLE: $(expr, [context])
// (which is just equivalent to: $(content).find(expr)
} else
return jQuery( context ).find( selector );
// HANDLE: $(function)
// Shortcut for document ready
} else if ( jQuery.isFunction( selector ) )
return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
return this.setArray(jQuery.makeArray(selector));
},
// The current version of jQuery being used
jquery: "1.2.5",
// The number of elements contained in the matched element set
size: function() {
return this.length;
},
当Dom加载jquery.js时立马就会执行init方法,这个时候init(selector, context)中参数selector传入的就是window这个对象,紧接着执行
if ( selector.nodeType ) {
this[0] = selector;
this.length = 1;
return this;
}
这样就初始化好了jQuery,$
对象;这里很有意思的是第一次初始化好后,当你在用$(id),jQuery(id)这个时候在顶头定义的var jQuery这个时候指向的是$(id)
返回后的对象,只有这样$(id)
这个变量
才能使用jquery的各种函数方法如attr,prop,在自己写js组件的时候也可以用这种思想,一般给定义对象都是下面这个样子
var test = {
a:function(){},
b:function(){},
c:function(){}
}
使用的过程只有test.a();test.b();test.c();就和$.each(),$.ajax()
一样,但$(“”)这种方式就很有意思,以后自己在写组件的时候也可以用这种思想;整个jquery.js 可以简化成如下
var jQuery = window.jQuery = window.$ = function(){
return new jQuery.init();
}
jQuery = {
init:function(){
return this;
},
val:function(){},
ready:function(){},
html:function(){}
`````
}
jQuery.fn.init.prototype = jQuery.fn;
jQuery.extend = jQuery.fn.extend = function(){`````};
})()
javascript 是面向对像的语言,创建对象都是通过new的方式,玩过prototype.js的人就明白,prototype.js创建对象都是通过new的方式
jquery是通过$()方式,这个主要就是由于在初始化的时候是调用自己的init方法,init方法是返回当前这个对象,这样就不用new
接下来看下jQuery.fn.init.prototype = jQuery.fn
,这个是为了使得init中this指向jQuery,说起来不是太清楚看代码
var myQuery = function(selector, context) {
var aa = new myQuery.prototype.init();
return aa;
}
myQuery.prototype = {
init: function() {
this.a = 1
return this;
},
a: 2,
b: function() {}
}
console.log(myQuery.b()); //无法找到name方法
接着加上
jQuery.fn.init.prototype = jQuery.fn
这个时候就可以了