Web常用工具 二维码美化 在线压缩 JavaScript AI工具汇总网站 ASP.NET控件源码查询 W3CHTML W3SCHOOL TypeScript 开源中国 51aspx github codeproject SQLBACKUP 几种排序算法比较 SQL中deny权限 MSDN下载 HttpWebRequest类 HTML5 stackoverflow ASP.NET 页生命周期概述 IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期概述 [SQL Server]视图sys.sysprocesses brnshop学习 SQL视频 Fiddler帮助文档 Sprint.Net SQLServer牛人博客 codeplex IIS官网 IE11 Developer Jquery源码视频上 Jquery源码视频下 Jquery Bugs jquery.miaov.com 正则表达式 Jquery API 1.9 Service Broker Javascript Object中的方法讲解 Microsoft webcast 微信开发接口 ECMAScript5 Underscore Jquery Bugs SQL存储过程事务嵌套 官网SQL事务锁 2345天气插件 Json数据查看 C++ jquery-plugin-validate 博学谷(传智播客) Swift视频 IOS代码论坛 SWIFT设计模式 操作系统下载 AngularJS VueJS ASPNETCORE 前端题库 Node.js ASPNETCORE 腾讯课堂 SwiftUI SwiftUI疑问解答 ADO.NET SMO 数字化企业网 Unicode码查询 Redis使用文档 .NET 微服务:适用于容器化 .NET 应用程序的体系结构 .NETCore5.0微软官方文档 CSS3.0 在 ASP.NET Core 中配置 Windows 身份验证 Maven使用教程 Maven Repository Thymeleaf Thymeleaf中文CSDN Spring官方文档 Spring中文文档 SpringBoot SpringData SVG在线设计工具 SVG教程01 SVG教程02 fontawesome图标库 mybatis官网 mybatis-spring中文 mysql教程 python教程 python的scrapy教程01 python的scrapy教程02 VS开发python xpath教程 腾讯向量数据库教程 JSZip浏览器内存中创建文件与文件夹 axios的使用文档 SheetJS(JS操作excel)的使用文档 金蝶云星空学习成长

huaan011

 

jQuery.extend 与 jQuery.fn.extend

extend方法为jQuery对象的核心之一,语法如下:

jQuery.extend([deep], target, object1, [objectN]),返回值Object。

概述:用一个或多个其它对象来扩展一个对象,返回被扩展的对象。

如果不指定target,则给Jquery命名空间本身进行扩展。这有助于插件作者为Jquery增加新方法。

如果第一个参数设置为true,则Jquery返回一个深层次的副本,递归地复制找到的任何对象。否则的话,副本会与原对象共享结构。未定义的属性将不会被复制,然而从对象的原型继承的属性将会被复制。

参数:target,[object1],[objectN]      Object,Object,Object 

target:一个对象,如果附加的对象被传递给这个方法将那么它将接收新的属性,如果它是唯一的参数将扩展jQuery的命名空间。

object1:待合并到第一个对象的对象。

objectN:待合并到第一个对象的对象。

[deep],target,object1,[objectN]        Object,Object,Object,Object

deep:如果设为true,则递归合并。

target:待修改对象。

object1:待合并到第一个对象的对象。

objectN:待合并到第一个对象的对象。

示例:      

 

var ts = function () {this.age = 23;}
console.log($.extend([1,2,3],[4,5,6,7])); 
// 结果:[4,5,6,7]
console.log($.extend(false, new ts(), { age: 12, name: "lisi" }));
//结果: Object {age: 12, name: "lisi"}
console.log($.extend({ age: 43, name: "张三" }, { sex: "男", height: 180 }, { job: "警察" }));
//结果:Object {age: 43, name: "张三", sex: "男", height: 180, job: "警察"}
console.log($.extend(true, { age: 23, child: { age: 1, sex: "男" } }, { name: '张三', child: { name: "李四" } }));
//结果:Object {age: 23, child: {age:1,name:'李四',sex:'男'}, name: "张三"}
console.log($.extend(false, { age: 23, child: { age: 1, sex: "男" } }, { name: '张三', child: { name: "李四" } }));
//结果:Object {age: 23, child: {name:"李四"}, name: "张三"}
console.log($.extend(true))
//结果: Object {}

 

在看源码之前我们先了解下深拷贝和浅拷贝:

浅拷贝 :仅仅复制对象的引用,而不是对象本身;

深拷贝:把复制的对象所引用的全部对象都复制一遍。

浅拷贝例子:

/* ================ 浅拷贝 ================ */
function simpleClone(initalObj) {
    var obj = {};
    for ( var i in initalObj) {
        obj[i] = initalObj[i];
    }
    return obj;
}

深拷贝例子:

/* ================ 深拷贝 ================ */
function deepClone(initalObj, finalObj) {
    var obj = finalObj || {};
    for (var i in initalObj) {
        if (typeof initalObj[i] === 'object') {
            obj[i] = (initalObj[i].constructor === Array) ? [] : {};
            arguments.callee(initalObj[i], obj[i]);
        } else {
            obj[i] = initalObj[i];
        }
    }
    return obj;
}

 

有了深拷贝和浅拷贝的介绍,我们再来看 Jquery.extend的源码分析:     

 

jQuery.extend = jQuery.fn.extend = function() {
    var src, copyIsArray, copy, name, 
        options, //20170614 huanhua 需要被合并的对象的临时变量
        clone,
        target = arguments[0] || {}, //huanhua 20170614 第一个参数赋值给 target ,需要合并到的对象 target
        i = 1, //huanhua 20170614 被合并的对象,在参数中的起始位置,默认是第二个参数,索引下标就是1
        length = arguments.length,
        deep = false; //huanhua 20170614 深浅拷贝,默认是浅拷贝

    // Handle a deep copy situation
  // 20170614 huanhua 处理类似 jquery.extend(true,{age:23,child:{age:1,sex:"男"}},{name:'张三',child:{name:"李四"}})这种扩展

    if ( typeof target === "boolean" ) {
        deep = target; //huanhua 20170614 设置是深拷贝还是浅拷贝
        target = arguments[1] || {}; //huanhua 20170614 此时需要合并到的对象是第二个参数
        // skip the boolean and the target
        i = 2; //20170614 huanhua 在进行深浅拷贝时,需要被合并的对象的起始位置是第3个参数,索引下标就是2开始
    }

    // Handle case when target is a string or something (possible in deep copy)
    // 20170614 huanhua 处理类似 $.extend("hshshdhd", [4, 5, 6, 7]) 结果:Object {0: 4, 1: 5, 2: 6, 3: 7}这种的扩展
    if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
        target = {}; //20170614 huanhua 被扩展的对象,扩展到一个对象上
    }

    // extend jQuery itself if only one argument is passed
    // 20170614 huanhau 处理类似 $.extend({name:"张哈"}) 这种,只有一个参数,并且还不是 $.extend(true)这种的参数格式
    //此时参数的长度是1,i也是1
    if ( length === i ) {
        target = this;//20170614 huanhua 需要扩展到的对象就是jquery自己
        --i; //20170614 huanhua 需要被合并的对象起始位置就是第一个参数,所以索引下标就是从 (--i)0开始
    }
    //20170614 huanhua 从需要被合并的对象的起始位置开始循环处理合并
    for ( ; i < length; i++ ) {
        // Only deal with non-null/undefined values
        //20170614 huanhua 把需要被合并的对象赋值给 options ,并且只处理 非 null,非 undefined 的对象
        if ( (options = arguments[ i ]) != null ) {
            // Extend the base object
            //20170614 huanhua 开始合并对象
            for ( name in options ) {
                //20170614 huanhua 在需要被扩展到的对象中寻找需要扩展的对象属性,并赋值给 src
                src = target[ name ];
                //20170614 huanhua 把需要被扩展的对象属性赋值给copy
                copy = options[ name ];

                // Prevent never-ending loop
                //20170614 huanhua var o={w:2} $.extend(o,{hao:o}),结果 Object {w:2} 处理这种扩展,在递归深拷贝的时候以防死循环
                //20170614 huanhua 譬如:
                // var o = { n: o };
                //    var xh = 0;
                //    var f = function (o) {
                //        for (var m in o) {
                //            console.log((xh++));
                //            console.log(m);
                //            f(m);
                //        }
                //    }
                //    f(o);
                // 在递归运行的时候,就是一个死循环
                if ( target === copy ) {
                    continue;
                }

                // Recurse if we're merging plain objects or arrays
                //20170614 huanhua 需要深拷贝deep,并且需要拷贝的属性copy是有效的(非null,非undefined),
                //并且需要拷贝copy的属性是纯粹的对象({a:1}或者new object())或者数组
                if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
                    //20170614 huanhua 拷贝的是数组
                    if ( copyIsArray ) {
                        copyIsArray = false;
                        //20170614 huanhua如果需要扩展到的对象中不存在属性src = target[ name ],或者不是数组格式的,
                        //就重新用生成一个空的数组 [] 来装载扩展的数据,否则就用原来的属性来装载数据
                        clone = src && jQuery.isArray(src) ? src : [];

                    } else {
                        //20170614 huanhua如果需要扩展到的对象中不存在属性src = target[ name ],或者不是纯粹对象格式的,
                        //就重新用生成一个空的对象 {} 来装载扩展的数据,否则就用原来的属性来装载数据
                        clone = src && jQuery.isPlainObject(src) ? src : {};
                    }

                    // Never move original objects, clone them
                    //20170614 huanhua 递归扩展属性对象中的每一个属性
                    target[ name ] = jQuery.extend( deep, clone, copy );

                // Don't bring in undefined values
                //20170614 huanhua 其它的合并就浅拷贝,直接赋值或者添加属性
                } else if ( copy !== undefined ) {
                    target[ name ] = copy;
                }
            }
        }
    }

    // Return the modified object 20170614 huanhua 返回合并后的对象
    return target;
};

 javascript的继承有三种方式

1:原型继承。

2:类式继承。

3:拷贝继承。

Juqery采用的就是拷贝继承。

这只是个人的理解,有不对之处,望各位大神们指正。

posted on 2017-06-13 09:17  华安  阅读(253)  评论(0编辑  收藏  举报

导航