$.extend.apply( null, [ true, { "a" : 1, "b" : 2 } ] );
//console.log(window.a); //window.location.reload();
$.extend.apply( null, [ true, { "a" : 1, "b" : 2 } ].concat( { "c" : 3, "d" : 4 } ) );
//console.log(window.a)

一、问题:

  1. null在这里是干啥?

  2. window.a分别是什么?

二、我们先一起来了解下jQuery中的extend函数

在jQuery-V1.2.6中:

jQuery.extend = jQuery.fn.extend = function() {
// copy reference to target object
var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; // Handle a deep copy situation
if ( target.constructor == 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" && typeof target != "function" )
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 ( var name in options ) {
var src = target[ name ], copy = options[ name ]; // Prevent never-ending loop
if ( target === copy )
continue; // Recurse if we're merging object values
if ( deep && copy && typeof copy == "object" && !copy.nodeType )
target[ name ] = jQuery.extend( deep,
// Never move original objects, clone them
src || ( copy.length != null ? [ ] : { } )
, copy ); // Don't bring in undefined values
else if ( copy !== undefined )
target[ name ] = copy; } // Return the modified object
return target;
};

jQuery - v1.2.6 extend

在jQuery-V1.8.2中:

jQuery.extend = jQuery.fn.extend = function() {
var options, name, src, copy, copyIsArray, 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 - V1.8.2 extend

比较两个版本的jQuery,extend函数总体构架上基本没有变化,高版本中写代码更加规范了,很多var变量都前置(这是比较好的编码习惯,当然,也是为了方便压缩工具对代码进行压缩)。

jQuery.fn.extend就是把extend函数绑定到他的原型链中。这样一来,既可以作为静态函数在$上直接引用($.extend),也可以在$(obj)上使用extend。

注意,如果函数没有在原型链上绑定,是不能被“继承”的!

代码大概的意思就是:

  第一个参数是boolean类型 ---------> 深度递归复制
|
|
---------> 如果只有一个参数(除第一个boolean)---------> 将函数的this环境extend进去
|
|
---------> 将后面的参数extend到“第一个”参数中 ---------> 返回“第一个”参数

三、问题解释

  •  第一个问题中,
$.extend.apply( null, [ true, { "a" : 1, "b" : 2 } ] );

extend作为一个静态函数被调用,null被绑定,但是因为满足“只有一个”参数(boolean除外)的条件 , 将函数的this环境(window)extend进去,return的对象就是window对象,所以得到的结果是

window <- { "a" : 1, "b" : 2 }

即,window.a = 1

  • 第二个问题中,
$.extend.apply( null, [ true, { "a" : 1, "b" : 2 } ].concat( { "c" : 3, "d" : 4 } ) );

相当于传入三个参数,第一个是true,第二个是 匿名对象{ "a" : 1, "b" : 2 },第三个是匿名对象{ "c" : 3, "d" : 4 }, 此时的this环境是null(因为将函数绑定到null上面了)。

那么结果就是{ "a" : 1, "b" : 2, "c" : 3, "d" : 4 }, 此刻并不能在window中索引到a这个属性

如要想要访问,那便是null.a,但这种访问方式肯定是不对的。

由于没有变量来接收这个返回的值,所以被作为垃圾给回收了。

有兴趣的童鞋可以试试这个:

$.extend.apply( $, [ true, { "a" : 1, "b" : 2 } ] );
$.extend.apply( $, [ true, { "a" : 1, "b" : 2 } ].concat( { "c" : 3, "d" : 4 } ) );

把$作为当前的环境,看看a被绑定在那个元素上了~

 四、小结

  jQuery是一个非常优秀的JS库,也是前辈们学习JS后经验的总结和思想的结晶,从jQuery1.2版本到现在的2.0版本,代码风格上、函数处理方式上有比较明显的改变,很值得花些功夫去研究。学习的过程中多看看ta们的编码风格、编码规范,了解库的整体构架和实现原理,这样应该会有比较大的提升~

  我觉得前端这方面想独树一帜,就必须在代码中体现自己的思想。

解读jQuery中extend函数的更多相关文章

  1. 解析jQuery中extend方法--源码解析以及递归的过程《二》

    源码解析 在解析代码之前,首先要了解extend函数要解决什么问题,以及传入不同的参数,会达到怎样的效果.extend函数内部处理传入的不同参数,返回处理后的对象. extend函数用来扩展对象,增加 ...

  2. jQuery.fn.extend() 函数详解

    jQuery.fn.extend()函数用于为jQuery扩展一个或多个实例属性和方法(主要用于扩展方法). jQuery.fn是jQuery的原型对象,其extend()方法用于为jQuery的原型 ...

  3. jQuery中$.extend(true,object1, object2);深拷贝对象

    语法:jQuery.extend( [deep ], target, object1 [, objectN ] ) 深浅拷贝对应的参数就是[deep],是可选的,为true或false.默认情况是fa ...

  4. jQuery中$.extend

    $.fn是指jquery的命名空间,加上fn上的方法及属性,会对jquery实例每一个有效. 如扩展$.fn.abc(),即$.fn.abc()是对jquery扩展了一个abc方法,那么后面你的每一个 ...

  5. 详细解读Jquery各Ajax函数:$.get(),$.post(),$.ajax(),$.getJSON()

    一,$.get(url,[data],[callback]) 说明:url为请求地址,data为请求数据的列表(是可选的,也可以将要传的参数写在url里面),callback为请求成功后的回调函数,该 ...

  6. 详细解读Jquery各Ajax函数

    $.get(),$.post(),$.ajax(),$.getJSON() 一,$.get(url,[data],[callback]) 说明:url为请求地址,data为请求数据的列表,callba ...

  7. 详细解读Jquery各Ajax函数:$.get(),$.post(),$.ajax(),$.getJSON() —(转)

    一,$.get(url,[data],[callback]) 说明:url为请求地址,data为请求数据的列表(是可选的,也可以将要传的参数写在url里面),callback为请求成功后的回调函数,该 ...

  8. 解析jQuery中extend方法--用法《一》

    extend方法在jQuery中是一个很重要的方法,jQuey内部用它来扩展属性方法.常用语jQuery插件开发. jQuery提供了两个方法,$.extend和$.fn.extend,两个方法内部实 ...

  9. jQuery中jsonp函数实现

    由于浏览器中的同源策略,不同的域名,不同的协议,甚至不同的端口都无法请求数据.因此出现了浏览器跨域请求数据问题. Jsonp是解决跨域问题的一个非常流行的方法. JSONP(JSON with Pad ...

随机推荐

  1. C/C++中extern关键字解析

    1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...

  2. jsp中,个别乱码进行转码操作

    来自大神 if(xh!=null && xh!=""){ xhmc =new String(xh.getBytes("ISO-8859-1"), ...

  3. 如何让电脑公司Win7系统自动关闭停止响应的程序

    在注册表编辑器窗口左侧,依次展开HKEY_CURRENT_USER\ControlPanel\Desktop,选中Desktop,在右边的窗口中选择AutoEndTasks,双击打开AutoEndTa ...

  4. Windows XP发行12周年,我正步入中年,你已垂暮

    2001年10月25日,Windows XP正式全球上市!作为Windows 2000的升级版本,XP拥有大量新的功能:新的用户界面.防火墙整合等,这些都大大的增强了系统的易用性和安全性.而微软将于2 ...

  5. .net 发展史

    2002年年初 -Visual Studio 2002 & .Net Framework 1.0 2003年春天 -Visual Studio 2003 & .Net Framewor ...

  6. K/3 Cloud开发之旅 -- 主页自定义篇(一)

    如果说我们要进行主页自定义篇,首先涉及到的就是登陆的自定义,那么如何进行登录界面的自定义呢 其实登陆界面自定义主要就是图片的替换 ,那么我们就看下登陆界面的图片的组成 登录页面底图有两部分组成,一个是 ...

  7. Linux 将文件夹下的所有文件复制到另一个文件里

    如何将文件夹/home/work下的文件复制到/home/temp里面? 使用命令: cp -R /home/work/* /home/temp *表示所有文件 但是/home/work 下的隐藏文件 ...

  8. listener监听器

    前言:之前写了一篇关于Filter的文章:http://tianweili.github.io/blog/2015/01/26/java-filter/,现在再来一篇Listener的,Filter和 ...

  9. [转]为什么使用 Redis及其产品定位

    原文链接:http://www.infoq.com/cn/articles/tq-why-choose-redis 传统MySQL+ Memcached架构遇到的问题 实际MySQL是适合进行海量数据 ...

  10. DWG2SHP DXF2SHP 如何把AutoCAD的DWG,DXF文件转换为Esri ArcGIS的Shape文件

    dwg是AutoCAD创立的一种图纸保存格式,已经成为二维CAD的标准格式,很多其他CAD为了兼容AutoCAD,也直接使用dwg作为默认工作文件. 地图shape文件由ESRI开发,一个ESRI的s ...