jquery的2.0.3版本源码系列(4):285-348行,extend方法详解
目录
1 . jquery extend的基本使用
通过285行的源码 jQuery.extend = jQuery.fn.extend = function() { ,extend方法要么是直接挂在到jQuery的静态方法,要么是挂载到fn上其实就是原型上(参考283行的赋值操作)的实例方法。extend方法可以传一个对象,类似于插件的方式,也可以传多个对象进行拷贝。
<script src="js/jquery-2.0.3.js"></script>
<script>
$.extend({
aaa:function(){
alert("1");
},
bbb:function(){
alert("2");
}
})
$.fn.extend({
aaa:function(){
alert("3");
},
bbb:function(){
alert("4");
}
})
$.aaa();//弹出1,静态方法可以直接调用
$().aaa();//弹出3,绑定到fn上的方法,以对象的形式调用
//多个对象参数,后面的对象会扩展到第一个对象上
var a={};
$.extend(a,{color:'#f40'});
console.log(a);//color所在的对象就被扩展到a对象上
</script>
接下来关注extend的拷贝分深拷贝和浅拷贝。
<script src="js/jquery-2.0.3.js"></script>
<script>
var a={};
var b={name:"hello"};
var c={name:"hello-1"};
var d={name:{age:20}};
var e={name:{age:50}};
//浅拷贝对象b
$.extend(a,b);
a.name="hi";
alert(b.name);//弹出hello
//浅拷贝对象d
$.extend(a,d);
a.name.age=30;
alert(d.name.age);//弹出30
//深拷贝对象c
$.extend(true,a,c);
a.name="hi";
alert(c.name);//弹出hello-1
//深拷贝对象e
$.extend(true,a,e);
a.name.age=40;
alert(e.name.age);//弹出50
</script>
2.代码简化版本
分为5个部分:
定义了一些变量
if(){} 是不是深拷贝
if(){} 参数正确不
if(){} 看是不是插件的情况,插件的话传入一个含有方法的json对象
for 传入多个对象的情况
if防止循环应用,if深拷贝,else if浅拷贝。
详解篇:3.1 定义了一些变量
var options, name, src, copy, copyIsArray, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false;
这里要说明一下target。它就是 $.extend(a,d); 拷贝的目标对象a。这里的arguments是javascript的内置对象,是一个类数组,索引为0的值当然是参数a。
详解篇:3.2 看是不是深拷贝
// 处理深拷贝的情形
if ( typeof target === "boolean" ) {
deep = target;
target = arguments[1] || {};
// 如果传入的第一个参数为true,那么deep就置为true了。target目标对象就调整为第二个。
//跳过布尔值和target
i = 2;
}
这里处理的是传入了true的情况,比如 $.extend(true,a,c); 。
详解篇:3.3 要传正确的的参数
// 如果传进来的并非object同时也不是function,那么target置为空对象。
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
target = {};
}
详解篇:3.4 处理插件的情形
// 如果传进来一个参数,那么target目标对象就为jquery自己。
if ( length === i ) {
target = this;
--i;
}
详解篇:3.5 传入多个对象的操作
基本思路是通过arguments进行取值,获取到每个非目标对象的参数。非target对象通过in循环,获取到属性名。
总体特征是浅拷贝只能拷贝一层,深拷贝可以连嵌套子对象也能拷贝进去。
浅拷贝的情况下,那么走的是else分支,对相应的值进行覆盖 target[ name ] = copy; 。可以看到如果原来有target有相同的属性,那么就覆盖,如果没有,那么就添加上。
<script src="js/jquery-2.0.3.js"></script>
<script>
var a={name:{age:20}};
var b={name:{age:50}};
//浅拷贝对象b
$.extend(false,a,b);
console.log(a);//{name:{age:20}}
console.log(b);//{name:{age:50}}
</script>
它遇到对象嵌套,copy这里是{age:50},通过简单的赋值是修改不了的。
<script>
var a={name:{age:20}};
var b={name:{age:50}};
a[name]=b[name];
console.log(a);//{name:{age:20}},没有变化哦。
</script>
深拷贝的情况下。copy是数组,src也为数组赋值给clone否则为空数组。copy是对象,src是对象赋值给clone否则为空对象。
<script src="js/jquery-2.0.3.js"></script>
<script>
var a={name:{age:20}};
var b={name:{age:50}};
//浅拷贝对象b
$.extend(true,a,b);
console.log(a);//{name:{age:50}}
console.log(b);//{name:{age:50}}
</script>
深拷贝的copy等于{age:50},src等于{age:20}。那么通过克隆的方式就可以把copy给到src。这其实是一个递归调用,所以深拷贝会拷贝到底。
for ( ; i < length; i++ ) {
// 处理非空或者没有定义的情况
if ( (options = arguments[ i ]) != null ) {
// 扩展基础对象,in语法把属性值取出来
for ( name in options ) {
src = target[ name ];
copy = options[ name ];
// 防止无限循环,类似$.extend(a,{name:a})。那么如果拷贝的某一个值就等于target那么就终止代码在继续循环
if ( target === copy ) {
continue;
}
// 深拷贝和copy存在,以及copy要么是对象、要么是数组
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 : {};
}
// 不移动原对象,克隆他们。
target[ name ] = jQuery.extend( deep, clone, copy );
// Don't bring in undefined values
} else if ( copy !== undefined ) {
target[ name ] = copy;
}
}
}
}
jquery的2.0.3版本源码系列(4):285-348行,extend方法详解的更多相关文章
- jquery的2.0.3版本源码系列(3):96行-283行,给JQ对象,添加一些方法和属性
jquery是面向对象的程序,面向对象就离不开方法和属性. 方法的简化 jQuery.fn=jQuery.prototype={ jquery: 版本 constructor: 修正指向问题 init ...
- jquery的2.0.3版本源码系列(2):21行-94行定义了一些变量和函数 jQuery=function(){}
2.1.bug通过索引查询 这里的#13335是bug的索引,如何查询呢? 第一步,浏览器地址栏输入"https://bugs.jquery.com/". 第二步,在网页的搜索框里 ...
- jquery的2.0.3版本源码系列(6):2880-3042行,回调对象,对函数的统一管理
目录 1 . 回调对象callbacks的演示 回调的使用有一点像事件绑定,先绑定好,等到有点击事件或者其他时就触发. <script src="js/jquery-2.0.3.js& ...
- jquery的2.0.3版本源码系列(7):3043行-3183行,deferred延迟对象,对异步的统一管理
目录 part1 deferred延迟对象 part2 when辅助方法 网盘源代码 链接: https://pan.baidu.com/s/1skAj8Jj 密码: izta part1 defe ...
- jquery的2.0.3版本源码系列(1)总体结构
为什么选择2.X版本,而不是1.X版本,因为2.X不兼容IE6/7/8,所以少了兼容代码,让我们更专注于jquery原理的代码. 一共有8830行. 1.1 匿名函数自执行 首先,匿名函数的作用是,把 ...
- jquery的2.0.3版本源码系列(5):349-817行,extend添加的工具方法
expando 生成唯一JQ字符串(内部)noconflict避免冲突isReady DOM是否加载完成(DOMContentLoaded)readyReady
- jQuery extend方法详解
先说个概念的东西: jQuery为开发插件提拱了两个方法,分别是: $.fn.extend(item):为每一个实例添加一个实例方法item.($("#btn1") 会生成一个 j ...
- jQuery 源码分析(十六) 事件系统模块 底层方法 详解
jQuery事件系统并没有将事件监听函数直接绑定到DOM元素上,而是基于数据缓存模块来管理监听函数的,事件模块代码有点多,我把它分为了三个部分:分底层方法.实例方法和便捷方法.ready事件来讲,好理 ...
- Kafka 0.10.1版本源码 Idea编译
Kafka 0.10.1版本源码 Idea编译 1.环境准备 Jdk 1.8 Scala 2.11.12:下载scala-2.11.12.msi并配置环境变量 Gradle 5.6.4: 下载Grad ...
随机推荐
- 开始编写寄几的 CSS 基础库
前言 在现在的互联网业务中,前端开发人员往往需要支持比较多的项目数量.很多公司只有 1-2 名前端开发人员,这其中还不乏规模比较大的公司.这时前端同学就需要独挡一面支持整个公司上下的前端业务,项目如流 ...
- 最短路径之Dijkstra算法和Floyd-Warshall算法
最短路径算法 最短路径算法通常用在寻找图中任意两个结点之间的最短路径或者是求全局最短路径,像是包括Dijkstra.A*.Bellman-Ford.SPFA(Bellman-Ford的改进版本).Fl ...
- 《HelloGitHub》第 16 期
<HelloGitHub>第 16 期 兴趣是最好的老师,HelloGitHub 就是帮你找到兴趣! 简介 分享 GitHub 上有趣.入门级的开源项目. 这是一个面向编程新手.热爱编程. ...
- (转)SQL Server基础之存储过程(清晰使用)
阅读目录 一:存储过程概述 二:存储过程分类 三:创建存储过程 1.创建无参存储过程 2.修改存储过程 3.删除存储过程 4.重命名存储过程 5.创建带参数的存储过程 简单来说,存储过程就是一条或 ...
- 初识 tk.mybatis.mapper
在博客园发表Mybatis Dynamic Query后,一位园友问我知不知道通用mapper,仔细去找了一下,还真的有啊,比较好的就是abel533写的tk.mybatis.mapper. 本次例子 ...
- 设置webstorm缩写代码
文件 ->设置->编辑器->活动模板->找到需要设置的文件类型(比如JavaScript)-->添加-(右上角)->设置模板之后,注意最后需要defind才能生效
- Dapper入门教程(一)——Dapper介绍
Dapper是什么? Dpper是一款.Net平台简单(Simple)的对象映射库,并且Dapper拥有着"微型ORM之王"的称号.就速度而言与手写ADO.NET SqlDateR ...
- 在drawRect:方法中绘制图片,文字以及Core Graphics 框架的了解
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #000000 } p.p2 { margin: 0.0px 0. ...
- C#使用Xamarin开发可移植移动应用(2.Xamarin.Forms布局,本篇很长,注意)附源码
前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 一点感想 很意外的,第一 ...
- 刚开始学python——数据结构——“自定义队列结构“
自定义队列结构 (学习队列后,自己的码) 主要功能:用列表模拟队列结构,考虑了入队,出队,判断队列是否为空,是否已满以及改变队列大小等基本操作. 下面是封装的一个类,把代码保存在myQueue.py ...