jquery源码解析:jQuery扩展方法extend的详解
jQuery中要扩展方法或者属性都是通过extend方法实现的。所谓的jQuery插件也是通过extend方法实现的。
jQuery.extend扩展的是工具方法,也就是静态方法。jQuery.fn.extend扩展的是实例方法。
当只传入一个对象的时候,里面的方法和属性是扩展到this上的。比如:
$.extend( { aaa:function(){}, bbb:function(){} } ) ,这里的this是$,所以用这种形式$.aaa()调用。
$.fn.extend( { aaa:function(){}, bbb:function(){} } ) ,这里的this是$.fn(原型),所以用这种形式$("").aaa()调用。
当传入多个对象的时候,后面的对象都是扩展到第一个对象身上。比如:
var a ={};
$.extend( a, {name:"hello"}, {age:30} ),这时a = {name:"hello",age:30}
还可以做深拷贝和浅拷贝(拷贝继承)。比如:
var a = {};var b = { name:{age:30} };
$.extend( a , b ); a.name.age = 20,这时你打印b.name.age,你会发现也是20.这就是浅拷贝。没有对对象进行复制,只对简单字符做了复制(如果name是字符串,那么改变a.name的值,即便是浅拷贝也不会影响b.name的值)。但是你可以使用深拷贝:
$.extend( true , a , b ); a.name.age = 20,这时你打印b.name.age,你会发现是30,没有改变。因为深拷贝,无论b的属性是什么,都会重新复制一份。
jQuery.extend = jQuery.fn.extend = function() {
var options, name, src, copy, copyIsArray, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false; //默认为浅拷贝
if ( typeof target === "boolean" ) { //看第一个参数是否是boolean
deep = target; //如果是,就证明目标对象是第二个参数,第一个参数是来判断是不是深拷贝的
target = arguments[1] || {};
i = 2;
}
if ( typeof target !== "object" && !jQuery.isFunction(target) ) { //必须 为对象或者函数
target = {};
}
if ( length === i ) { //如果只有一个对象的时候,目标对象指向this,往this上扩展方法和属性
target = this;
--i;
}
for ( ; i < length; i++ ) {
if ( (options = arguments[ i ]) != null ) { //判断扩展的对象不是null
for ( name in options ) { //取对象中的属性名
src = target[ name ]; //取目标对象的name属性值
copy = options[ name ]; //取扩展对象的name属性值
if ( target === copy ) {
//解决循环引用的问题,比如:var a ={};$.extend( a , { name:a } ),如果不做这个处理,将会得到一个死循环的对象(a{name:{name:{name:{...}}}}),加了这个,就扩展不上,a还是{}
continue;
}
if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
//如果是深拷贝,并且扩展对象的name属性值存在,并且扩展对象是一个对象自变量(或者是一个数组),就进入if语句
if ( copyIsArray ) { //如果扩展对象的name属性值是数组,进入if语句
copyIsArray = false;
clone = src && jQuery.isArray(src) ? src : [];
//如果目标对象的name属性值是一个数组,就取这个数组,如果不是,就取[]
} else { //如果扩展对象的name属性值是对象自变量
clone = src && jQuery.isPlainObject(src) ? src : {};
//如果目标对象的name属性值是一个对象自变量,就取这个对象自变量,如果不是,就取{}
}
target[ name ] = jQuery.extend( deep, clone, copy );
//递归调用extend,深拷贝扩展对象的name属性值(对象或者数组)到clone。
//递归结束后,返回clone,赋值给目标元素的name属性
//这就把扩展对象的所有属性都扩展到目标对象中了。
} else if ( copy !== undefined ) {
target[ name ] = copy;
}
}
}
}
return target;
}
jQuery中使用的是拷贝继承。
加油!
jquery源码解析:jQuery扩展方法extend的详解的更多相关文章
- jQuery 源码解析(三十) 动画模块 $.animate()详解
jQuery的动画模块提供了包括隐藏显示动画.渐显渐隐动画.滑入划出动画,同时还支持构造复杂自定义动画,动画模块用到了之前讲解过的很多其它很多模块,例如队列.事件等等, $.animate()的用法如 ...
- jQuery 源码分析(十九) DOM遍历模块详解
jQuery的DOM遍历模块对DOM模型的原生属性parentNode.childNodes.firstChild.lastChild.previousSibling.nextSibling进行了封装 ...
- jQuery 源码解析(三) pushStack方法 详解
该函数用于创建一个新的jQuery对象,然后将一个DOM元素集合加入到jQuery栈中,最后返回该jQuery对象,有三个参数,如下: elems Array类型 将要压入 jQuery 栈的数组元素 ...
- jQuery 源码分析(十) 数据缓存模块 data详解
jQuery的数据缓存模块以一种安全的方式为DOM元素附加任意类型的数据,避免了在JavaScript对象和DOM元素之间出现循环引用,以及由此而导致的内存泄漏. 数据缓存模块为DOM元素和JavaS ...
- jQuery源码分析(九) 异步队列模块 Deferred 详解
deferred对象就是jQuery的回调函数解决方案,它解决了如何处理耗时操作的问题,比如一些Ajax操作,动画操作等.(P.s:紧跟上一节:https://www.cnblogs.com/grea ...
- 十七.jQuery源码解析之入口方法Sizzle(1)
函数Sizzle(selector,context,results,seed)用于查找与选择器表达式selector匹配的元素集合.该函数是选择器引擎的入口. 函数Sizzle执行的6个关键步骤如下: ...
- jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究
终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...
- jquery源码解析:代码结构分析
本系列是针对jquery2.0.3版本进行的讲解.此版本不支持IE8及以下版本. (function(){ (21, 94) 定义了一些变量和函数, jQuery = function() ...
- JQuery源码解析(一)
写在前面:本<JQuery源码解析>系列是基于一些前辈们的文章进行进一步的分析.细化.修改而写出来的,在这边感谢那些慷慨提供科普文档的技术大拿们. 要查阅JQ的源文件请下载开发版的JQ.j ...
随机推荐
- screen command of linux
[screen command of linux] 常用键: 补充: Ctrl-a S # split terminal horizon Ctrl-a TAB # switch to ano ...
- Kibana(elasticsearch操作工具)的安装
在安装完es集群的基础上 1.创建文件夹并赋权 # 使用root进行操作 mkdir -p /export/data/kibana mkdir -p /export/logs/kibana # 赋权给 ...
- opencv cv::imageshow 不加waitKey()不能显示图片
官方解释是highgui 没有给imshow绘制处理的时间.需要在imshow添加waitKey() waitKey()单位是ms
- Ubuntu14.04下opencv卸载与重装
参考链接:http://askubuntu.com/questions/334158/installing-opencv http://stackoverflow.com/questions/1313 ...
- vue与django中预防CSRF
一.环境: vue2.0.django 1.10.x.iview 二.django后台处理 1.将django的setting的MIDDLEWARE中加入django.middleware.csrf. ...
- Thread.sleep原理
我们可能经常会用到 Thread.Sleep 函数来使线程挂起一段时间.那么你有没有正确的理解这个函数的用法呢?思考下面这两个问题: 假设现在是 2008-4-7 12:00:00.000,如果我调用 ...
- [C++] printf pitfall
printf pitfal l
- linux ubuntu 各目录大小
/home 45k /bin 8.7M /lib 370M /mnt 4.1k /run 36k /sbin 11M /tmp 41k /usr/share 770M
- Windows下如何安装MongoDB
下载地址: http://www.mongodb.org/downloads 我下载的是:mongodb-win32-x86_64-2008plus-2.6.6 解压到:D:\soft 同时在该目录下 ...
- C# chart.DataManipulator.FinancialFormula()公式的使用 线性回归预测方法
最近翻阅资料,找到 chart.DataManipulator.FinancialFormula()公式的使用,打开另一扇未曾了解的窗,供大家分享一下. 一 DataManipulator类 运行时, ...