jQuery源码学习

$、jQuery是什么?

  平时天天在用的$到底是个什么东西?$("id")思考,感觉像个工厂方法。提供selector创建jquery对象。
  一看源码绕晕了,剥茧抽丝吧
 
定义jquery对象,原型上添加方法
function _jQuery(selector){}
_jQuery.prototype={...}
****************************************************
想更简洁的创建jQuery对象
jQuery=function(selector){
    return new _jQuery(selector);
}
function _jQuery(selector){}
创建一个快捷接口方便修改jQuery原型
jQuery.fn=_jQuery.prototype={...}
****************************************************
将_jQuery挂到jQuery的原型属性init上
jQuery.prototype.init=_jQuery=function(selector){
    ...
}
jQuery.fn=_jQuery.prototype={...}=jQuery.prototype.init.prototype
jQuery=function(selector){
    return new jQuery.prototype.init(selector);
}
****************************************************
将_jQuery去掉
jQuery.prototype.init=function(selector){
    ...
}
jQuery.fn={...}=jQuery.prototype.init.prototype
jQuery=function(selector){
    return new jQuery.prototype.init(selector);
}

看到这里应该明白了平时我们用的最多jQuery($)只是个包装方法。
为了方便我们扩展实际的_jQuery对象(jQuery.prototype.init)原型暴露出$.fn,
在这基础上jQuery.fn=jQuery.prototype让我们用的更习惯。
所以最后出来这绕来绕去略显奇葩的源码:

jQuery=function(selector){
    return new jQuery.prototype.init(selector);
}
jQuery.fn=jQuery.prototype={
    ...
    init:function(){...}
}

 细不细很开心哦,豁然开朗

$.extend是做什么的?

  这个接口有点灵活,还是看过源码后用起来才有底气


jQuery.extend = jQuery.fn.extend = function() { var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !jQuery.isFunction(target) ) { target = {}; } // extend jQuery itself if only one argument is passed if ( length === i ) { target = this; --i; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) { // Extend the base object for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && jQuery.isArray(src) ? src : []; } else { clone = src && jQuery.isPlainObject(src) ? src : {}; } // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; };

jquery 的$.extend经常用的,参数灵活给人有点混乱的感觉,有时不注意可能会使用不当遇到坑。

$.extend(true,objA,objB,objC)  第一参数如果是boolean类型,则用来标明是否深克隆拷贝对象。将objB深克隆拷贝到objA,再将objC深克隆拷贝到objA
 
$.extend(objA,objB,objC)   若第一个参数不为boolean,则用直接值复制的方式拷贝对象,第一个参数对象(包括object、array、function类型)定义为target目标对象:将objB值复制到objA,再将objC复制到objA
 
$.extend(objA)         如果只有一个参数对象,则target目标对象设为this($.fn/$):将objA属性值赋值给$.fn/$
 
例:
获得A对象的深拷贝               $.extend(true,{},A);
克隆A对象同时,获得B、C对象的属性。      $.extend(true,{},A,B,C);
jquery插件写法                
$.extend({
 center:function(){...}
});
=$.fn.center=function(){...}  
 

$.Deferred $.callback的用途?

 

jquery对于方法回调有2个很有意思的封装$.Deferred,$.callback。各有各的适用场景:

$.callback("rule") :

1.维护一个有规则的回调方法列表,提供add、fire、remove接口给调用者

2.关注的是多个事件以何种逻辑调用

3.作为回调方法的中间层,将方法的执行fire和方法的监听add、remove解耦

 

规则rule:

once 每次调用后方法置空
memory add新方法时,调用上一次fire的参数值触发当前方法
unique 不重复
stopOnFalse false 执行链中断

function fn1( value ){
    console.log( value );
    return false;
}

function fn2( value ){
    fn1("fn2 says:" + value);
    return false;
}
    
var callbacks = $.Callbacks( "unique memory" );
callbacks.add( fn1 );
callbacks.fire( "foo" );
callbacks.add( fn1 ); // repeat addition
callbacks.add( fn2 );
callbacks.fire( "bar" );
callbacks.add( fn2 );
callbacks.fire( "baz" );
callbacks.remove( fn2 );
callbacks.fire( "foobar" );

/*
output:
foo
fn2 says:foo
bar
fn2 says:bar
baz
fn2 says:baz
foobar
*/

 

$.Deferred

1.作为回调方法中间层,解耦事件的定义dfd.done(fn).fail(fn)和方法的执行dfd.resolve(ars)
2.支持链式,擅长控制处理事件调用的时机
3.提供灵活的接入代码方式:最强大的莫过于$.Deferred()可以接受一个函数参数,$.Deferred()所生成的deferred对象将作为这个函数的默认参数。

        function wait(dtd){
            setTimeout(function(){
                dtd.resolve("yinshen");
            },2000);
        }        
        /**最基础的实现,传入Deferred对象
        var dtd=$.Deferred();
        dtd.done(function(data){
            console.log(data);
        });
        wait(dtd);
        **/
        /**定义实现Deferred接口
         * 
        var dtd=$.Deferred();
        dtd.promise(wait);
        wait.done(function(data){
            console.log(data);
        });    
        wait(dtd);
        **/        
        /**将自己包装成Deferred对象,简洁**/
        $.Deferred(wait).done(function(data){
            console.log(data);
        });    

 

posted on 2013-03-16 22:28  西瓜SY  阅读(221)  评论(0编辑  收藏  举报