javascript代码实例教程-对jQuery.extend()方法的分析

发布时间:2019-01-22 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了javascript代码实例教程-对jQuery.extend()方法的分析脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。 jQuery.extend方法是我们常用的方法,也是jquery码中的基础方法。它的主要作用是:将一个或多个“源对象”合并到一个“目标对象”中,并返回目标对象。它主要有三种表现形式:

 

a、jQuery.extend(destination, source1, source2, source3 ....)

 

b、jQuery.extend( source )

 

c、jQuery.extend(boolean, destination, source1, source2, source3 ....)

 

a方式第一个参数作为“目标对象”,其它参数作为“源对象”。

 

b方式只有一个参数,这里的这个参数变成了“源对象”,“目标对象”变成了jQuery。说白了就是"源对象"的属性,变成jQuery函数的静态方法或属性。

 

c方式的第一个参数是boolean类型的,第二个参数是"目标对象",剩下的参数是“源对象”。当第一个参数的值为true时,表示对象合并时支持“深拷贝”。

 

知道了函数的用法,我们肯定好奇jQuery是怎么实现的,想看看jQuery的源码。不过在看jQuery源码之前,我们不妨试着写写这个方法的功能,然后在回过头来看jQuery源码,感受可能更深,看到的东西可能越多。

 

我们先不要给自己压力,先从最简单开始,要实现的方法就两个参数:第一个参数是:“目标对象”,第二个参数是:“源对象”。先实现把“源对象”合并到“目标对象”中。代码如下:

 

复制代码

VAR test = function(){}

Test.extend0 = function(destination, source){

    for(var key in source){

        destination[key] = source[key]

    }

    return destination

}

复制代码

第二步实现可以传入多个参数,第一个参数是目标对象,其他参数是源对象。代码如下:

 

复制代码

Test.extend1 = function(){

    var destination = arguments[0]

    var sourceArr = Array.PRototyPE.slice.call(arguments,1)

    for(var i = 0, len = sourceArr.length; i < len; i++){

        var source = sourceArr[i]

        for(var key in source){

            destination[key] = source[key]

        }

    }

    return destination

}

复制代码

第三步实现只有一个参数时,将参数对象的属性附加给Test。代码如下:

 

复制代码

Test.extend2 = function(){

    var argumentsLen = arguments.length

    if( argumentsLen === 1 ){

        var source = arguments[0]

        for(var key in source){

            Test[key] = source[key]

        }

    }else{

        var destination = arguments[0]

        var sourceArr = Array.prototype.slice.call(arguments,1)

        for(var i = 0, len = sourceArr.length; i < len; i++){

            var source = sourceArr[i]

            for(var key in source){

                destination[key] = source[key]

            }

        }

        return destination

    }

}

复制代码

第四步实现“深拷贝”,第一个参数是是否进行深拷贝的布尔判断,第二个参数是目标对象,其他参数是源对象。代码如下:

 

复制代码

Test.extend3 = function(){

    var argumentsLen = arguments.length

    if( argumentsLen === 1 ){

        var source = arguments[0]

        for(var key in source){

            Test[key] = source[key]

        }

    }else{

        var FirstITem = arguments[0]

        var isBoolean = typeof firstItem === "boolean"

        var destination = isBoolean ? arguments[1] : firstItem

        var startNum = isBoolean ? 2 : 1

        var sourceArr = Array.prototype.slice.call(arguments,startNum)

        for(var i = 0, len = sourceArr.length; i < len; i++){

            var source = sourceArr[i]

            if( isBoolean ){

                deepExtend( destination, source )

            }else{

                for(var key in source){

                    destination[key] = source[key]

                }

            }

        }

        return destination

    }

}

 

function deepExtend(destination, source){

    for(var key in source){

        var value = source[key]

        if( value instanceof Array ){

            destination[key] = arguments.callee.call( destination[key] || [], value )

        }else if( value instanceof Object ){

            destination[key] = arguments.callee.call( destination[key] || {}, value )

        }else{

            destination[key] = source[key]                

        }

    }

    return destination

}

复制代码

好了,我们按照自己的思路,粗略的实现了自己的extend方法,现在就看下jQuery对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;

 

        // skip the boolean and the target

        target = arguments[ i ] || {};

        i++;

    }

 

    // 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 ( i === length ) {

        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&#39;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;

}

复制代码

通过对比,我们发现:

 

a、jQuery在代码组织和实现上更加优雅。

 

b、jQuery考虑到了一些特殊情况。比如:

 

if ( target === copy ) {

      continue;

}

这是为了避免无限循环,“源对象”的属性指向的是“目标对象”,当合并对象时,也就是将“自己”复制为“自己的属性”。这是不可取的。

 

c、jQuery在数组(jQuery.isArray)和“纯粹对象”(jQuery.isPlainObject)的判断上,考虑的更精细。

 

先自己想思路去实现,再反过来对比学习,这种学习方法感觉挺好的。a、加强了独立思考能力。b、发现新的学习内容。c、暴漏自己的不足。

觉得可用,就经常来吧! 脚本宝典 欢迎评论哦! js脚本,巧夺天工,精雕玉琢。小宝典献丑了!

脚本宝典总结

以上是脚本宝典为你收集整理的javascript代码实例教程-对jQuery.extend()方法的分析全部内容,希望文章能够帮你解决javascript代码实例教程-对jQuery.extend()方法的分析所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。