整体架构:
jQUery.fn = jQUery.prototype = {
constructor: jQUery,
init : function(selector, context, rootjQuery){}
selector: "";
jquery: "1.7.1",
length: 0,
size: function(){},
toArray: function(){},
get: function(){},
pushStack: function(elems, name, selector){},
each: function(callback, args){},
ready: function(fn){},
eq: function(i){},
first: function(){},
last: function(){},
slice: function(),
map: function(callback){},
end: function(){},
push: push,
sort: [].sort,
splice: [].splice
}
一、selector、.jquery、.length、.size()
selector用于记录jQuery查找和过滤DOM元素时的选择器表达式
ex:
$('div').find('p').selector //"div p"
#('div p').selector //"div p"
二、toArray()、.get([index])
1、toArray()
.toArray()借用数组方法slice()将当前jQuery对象转换为真正的数组
源码:
toArray: function(){
return Array.prototype.slice.call(this, 0);
},
复习 call()、 apply()
2.get([index])
返回当前jQuery对象中制定位置的元素或包含了全部元素的数组。
如果没参数,则调用.toArray()返回包含了所有元素的数组。
如果指定了参数index,则返回一个单独的元素;
参数index从0开始计算,并支持附属,负数表示从元素集合末尾开始计算
get: function(num){
return num == null? this.toArray(): (num < 0 ? this[ this.length + num ]:this[num])
}
三、each(function(index,Element))、jQuery.each(collection,callback(indexInArray, valueOfElement))
1、.each()遍历当前对象,并在每个元素上执行回调函数。当回调执行时,会传递当前循环次数作为参数,从0开始计数;
回调函数是在当前元素为上下文的语境中触发的,即关键字this总是指向当前元素;回调函数中返回false可以终止遍历;
each: function(callback, args){
return jQUery.each(this,callback, args)
}
2、jQuery.each(collection, callback(indexInArray, valueOfElement))
静态方法jQuery.each()是个通用的遍历迭代方法,用于无缝遍历对象和数组。对于含有length属性的类数组对象,该方法通过下标遍历。
对于其他对象则通过属性名遍历(for-in),遍历过程中,如果回调函数返回false,则遍历结束
jQuery源码:
each: function( object, callback, args ) {
//object:待遍历的对象和数组
//callback:对数组或对象每个属性都执行的回调函数
//args:传给回调函数callback的参数数组,如果没有传入参数args,则执行回调时传入两个参数(下标(属性)、对应元素(属性值)),如果传入了args,则只把该参数传给回调函数
var name, i = 0,
length = object.length,
isObj = length === undefined || jQuery.isFunction( object );
if ( args ) {
//如果传入参数args
if ( isObj ) {
for ( name in object ) {
if ( callback.apply( object[ name ], args ) === false ) {
break;
}
}
} else {
for ( ; i < length; ) {
if ( callback.apply( object[ i++ ], args ) === false ) {
break;
}
}
}
// A special, fast, case for the most common use of each
} else {
//不传args
if ( isObj ) {
for ( name in object ) {
if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
break;
}
}
} else {
for ( ; i < length; ) {
if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
break;
}
}
}
}
return object;
//返回传入的形参object来支持链式语法
}
四、 .map(callback(index,domElement))、jQuery.map(arrayOrObject, callback(value, indexOrKey))
1、 .map()遍历当前jQuery对象,在每个元素上执行回调函数,并将回调函数的返回值放入一个新jQuery对象中,常用于获取或设置DOM元素集合的值
方法.map()内部通过静态方法jQuery.map()和圆形方法.pushStack()实现,相关代码如下所示:
map: function(callback){
return this.pushStack(jQUery.map(this, function(elem,i){
return callback.call(elem, i, elem);
}));
}
2、jQuery.map(arrayOrObject, callback(value, indexOrKey))
对数组中每个元素或对象的每个属性调用一个回调函数,并将回调函数的返回值放入一个新的数组中。
回调函数执行时需要两个参数:1、数组元素或属性值,2、元素下标或属性名。
关键字this指向全局对象window,回调函数的返回值会被放入新文组
源码:
// arg is for internal usage only
map: function( elems, callback, arg ) {
// elems:待遍历的数组或对象;
// callback:回调函数,会在数组每个元素或对象上执行
// args:仅限jQuery内部使用,如果调用jQuery.map()时传入了参数arg,则会传给回调函数callback
var value, key, ret = [],
i = 0,
length = elems.length,
// jquery objects are treated as arrays
isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
// Go through the array, translating each of the items to their
if ( isArray ) {
for ( ; i < length; i++ ) {
value = callback( elems[ i ], i, arg );
if ( value != null ) {
ret[ ret.length ] = value;
}
}
// Go through every key on the object,
} else {
for ( key in elems ) {
value = callback( elems[ key ], key, arg );
if ( value != null ) {
ret[ ret.length ] = value;
}
}
}
// Flatten any nested arrays
return ret.concat.apply( [], ret );
},
五、 .pushStack(elements, name, arguments)
原型.pushStack()创建一个新的空jQuery对象,然后把DOM元素集合放入这个jQuery对象中,并保留对当前jQUery对象的引用。
原型方法.pushStack()是核心方法之一,为很多方法提供了支持
// Take an array of elements and push it onto the stack
// (returning the new matched element set)
pushStack: function( elems, name, selector ) {
// Build a new jQuery matched element set
var ret = this.constructor();
if ( jQuery.isArray( elems ) ) {
push.apply( ret, elems );
} else {
jQuery.merge( ret, elems );
}
// Add the old object onto the stack (as a reference)
ret.prevObject = this;
ret.context = this.context;
if ( name === "find" ) {
ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
} else if ( name ) {
ret.selector = this.selector + "." + name + "(" + selector + ")";
}
// Return the newly-formed element set
return ret;
},
六、 .end()
结束当前链条中最近的筛选操作,并将匹配元素集合还原为之前状态
end: function(){
return this.prevObject || this.consgructor(null);
}