解析jQuery.extend和淘宝KISSY.mix方法源码

一、jQuery.extend方法

1、用途

     jQuery.extend方法是将多个对象(提供对象)的属性(包括原型中的属性)复制给另一个对象(要扩展的目标对象),使目标对象增强行为;当提供对象有而目标对象没有的属性(包括方法),则直接复制给目标对象,

当它们有相同的属性名(即key键相同),且值为对象,设置参数deep = true时,数组和简单对象会递归合并,否则直接覆盖,不会合并。

 

2、用法

jQuery.extend( target, [ object1 ], [ objectN ] )
target 一个对象,如果附加的对象被传递给这个方法那么它将接收新的属性,如果它是唯一的参数将扩展jQuery的命名空间
object1 一个对象,它包含额外的属性合并到第一个参数

objectN 包含额外的属性合并到第一个参数

jQuery.extend( [ deep ], target, object1, [ objectN ] )
deep 如果是true,合并成为递归(又叫做深拷贝)。
target 对象扩展。这将接收新的属性。
object1 一个对象,它包含额外的属性合并到第一个参数
objectN 包含额外的属性合并到第一个参数

3、源码解析
复制代码
// 源码解析 update-time:2014/05/20
(function( window, undefined ) {
    var jQuery = function() {
        // ...
    };
    jQuery.extend = function() {
        // 提供合并的对象,提供合并对象的属性,目标对象的属性值,提供合并对象的属性值
        // 布尔值(判断提供的合并对象属性值类型是否为数组),递归中的目标对象(目标对象的属性),目标对象
        var options, name, src, copy, copyIsArray, clone,
            target = arguments[0] || {},
            i = 1,
            length = arguments.length,
            deep = false;

        // 处理第一个参数为boolean类型
        if ( typeof target === "boolean" ) {
            deep = target;
            target = arguments[1] || {};
            // 略过第一个boolean类型参数和目标扩展对象,提供合并属性的对象从第三个参数开始
            i = 2;
        }

        // 目标参数类型不是对象、函数,则重置为一个新的空对象
        if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
            target = {};
        }

        // 当参数只有一个,扩展jQuery本身( this指向jQuery )
        if ( length === i ) {
            target = this;
            // 提供合并属性的对象从第一个参数开始
            --i;
        }

        // 枚举提供合并的对象
        for ( ; i < length; i++ ) {
            // 提供合并的对象不为null,注意这里比较的是值,不包括null类型
            if ( (options = arguments[ i ]) != null ) {
                // 枚举提供合并对象的属性
                for ( name in options ) {
                    src = target[ name ];
                    copy = options[ name ];
     
                    // 当目标对象与被复制属性值指向同一引用,则跳出本次循环
                    if ( target === copy ) {
                        continue;
                    }
     
                    // 被复制属性值的类型为对象、数组
                    if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
                        // 指定递归中要扩展的目标为数组
                        if ( copyIsArray ) {
                            copyIsArray = false; // 需要重置为false,因为jQuery.isPlainObject(copy)为true时,始终都是执行第一个if语句
                            clone = src && jQuery.isArray(src) ? src : [];
                        } 
                        // 指定递归中要扩展的目标为对象
                        else {
                            clone = src && jQuery.isPlainObject(src) ? src : {};
                        }

                        // 使用jQuery.extend方法进行递归
                        target[ name ] = jQuery.extend( deep, clone, copy );
     
                    // 被复制属性值的类型不是对象、数组、undefined,则将被复制属性值赋值到目标对象中
                    } else if ( copy !== undefined ) {
                        target[ name ] = copy;
                    }
                }
            }
        }
     
        // 返回被合并的对象,即目标对象
        return target;
    };
     
    // 扩展jQuery命名空间下的方法,增强行为
    jQuery.extend({
        method: function () {
            console.log('test');
        },
        noConflict: function () {
            //...   
        },
        isReady: false,
        // ...
    });
 
    window.jQuery = window.$ = jQuery;
 
})( window );
View Code
复制代码
    测试代码如:
1
jQuery.method(); // test
    注意:通过jQuery.extend扩展jQuery本身的方法,是jQuery的静态方法,不能在带有选择器的jQuery对象上使用。


二、KISSY.mix方法(KISSY1.20版本)

1、用途

与jQuery.extend方法用途相似,不过KISSY.mix只允许一个提供对象参数,参数也不同。

2、用法


KISSY.mix(receiver , supplier [ , overwrite = true , whitelist , deep ]) supplier 对象的成员复制到 receiver 对象上.
    receiver (object) – 属性接受者对象.
    supplier (object) – 属性来源对象.
    overwrite (boolean) – 是否覆盖接受者同名属性.
    whitelist (Array<string>) – 属性来源对象的属性白名单, 仅在名单中的属性进行复制.
    deep (boolean) – 是否进行深度 mix (deep copy)

3、源码解析

     测试代码如:

1
KISSY.method(); //test

 

posted @   杨君华  阅读(2812)  评论(2编辑  收藏  举报
编辑推荐:
· .NET Core 对象分配(Alloc)底层原理浅谈
· 聊一聊 C#异步 任务延续的三种底层玩法
· 敏捷开发:如何高效开每日站会
· 为什么 .NET8线程池 容易引发线程饥饿
· golang自带的死锁检测并非银弹
阅读排行:
· 一个适用于 .NET 的开源整洁架构项目模板
· AI Editor 真的被惊到了
· API 风格选对了,文档写好了,项目就成功了一半!
· 【开源】C#上位机必备高效数据转换助手
· .NET 9.0 使用 Vulkan API 编写跨平台图形应用
点击右上角即可分享
微信分享提示