jquery 源码分析-核心(3)noConflict和each
noConflict方法
noConflict: function( deep ) {
//_$ 是一个undefined,这个时候其他库就可以使用$关键字
//(假设其他库也是将方法绑定到window.$)
//如果deep为true,也就是说明jQuery这个关键字也被其他的使用了,
// 需要用其他库,$.noConflict(true),这样其他库就可以使用了
window.$ = _$;
if ( deep )
window.jQuery = _jQuery; //_jQuery 是一个undefined
return jQuery;
},
noConflict方法是在出现jQuery
库的$
对象和其他库冲突时,我们可以用jQUery
这个对象,这样就可以接着使用jQuery
的方法,这个设计实在是太妙来,通过定义2个对象来避免在冲突时可以接着使用jQuery
,jQuery
的作者在第一个版本就有了这个方法,真是很有远见,在我们自己写js框架的时候可以使用这个思想,绝地是好的不要不要的。,我还是想用$对象怎么办,这个时候,匿名函数和闭包就排上用场了,如下
jQuery.noConflict();
(function( $ ) {
$(function() {
这个地方我们就可以用$(),了
});
})(jQuery);
这个玩法其实是本质用的是jQuery
对象,只是用 $
参数代替了jQUery
,看起来用的是$
要是最悲剧的情况发生了,$
和jQuery
都被别的库暂用了咋办,那还是有办法的
var dom = {};
dom.query = jQuery.noConflict( true );
//dom.query就可以使用jquery的各种方法 如
dom.query( "div p" ).hide();
each方法
常见使用each的地方是,迭代对象或者数组 如下
1. 遍历对象
var object1 = {a:1,b:2,c:3};
$.each(object1,function (index,item) {
console.log(index+"/"+item); // a/1;b/1
});
2. 遍历数组(也可以是一个dom数组 如object2 = $(tabaleId).find(‘tr’))
var object2 = [{a:1,b:1},{a:2,b:2}];
$.each(object2,function (index,item) {
console.log(index+"/"+JSON.stringify(item)); // 0/{"a":1,"b":1};1/{"a":2,"b":2
});
3. 自定义参数,这种用法比较少见,用第二种也是可以实现这个的,这个只是减少一些代码,可读性不是太好,不推荐使用
var object2 = [{a:1,b:1},{a:2,b:2}];
$.each(object2,function (a,b) {
this[a] = b;
console.log(JSON.stringify(this)); // {"a":1,"b":1,"c":1},{"a":2,"b":2,"c":1}
},["c",1]);
源码
each: function( object, callback, args ) {
//callback 就是function(index,item){}
var name, i = 0, length = object.length;
//args是自定义参数,记得必须是一个数组
if ( args ) {
if ( length == undefined ) {
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 {
// if 为true,就表明object是一个对象,为false就是一个数组
if ( length == undefined ) {
for ( name in object )
if ( callback.call( object[ name ], name, object[ name ] ) === false )
break;
} else
for ( var value = object[0];
i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
}
return object;
}
这个源码主要是看callback.apply 和callback.call,这个2个用法很好的说明apply与call方法的差别,apply传入的是对象,和参数数组;call 传入的是对象和每个对应的参数,所以在参数不清楚的情况下,用apply,清楚明了的情况下用 call,源码里在if ( args ) 为true的时候,用的是apply,因为这个时候,源码只知道callback有这么个参数,但并不知道具体的值,;再看if ( args )为false时,这个时候源码清楚的规定了callback方法为function(index,item){},所以用call方法,二者差别可以看下面例子
theFunction.apply(valueForThis, arrayOfArgs)
theFunction.call(valueForThis, arg1, arg2, ...)
Simple Code
function theFunction(name, profession) {
console.log("My name is " + name + " and I am a " + profession + ".");
}
theFunction("John", "fireman");
theFunction.apply(undefined, ["Susan", "school teacher"]);
theFunction.call(undefined, "Claude", "mathematician");
// My name is John and I am a fireman.
// My name is Susan and I am a school teacher.
// My name is Claude and I am a mathematician.