jQuery 源码学习 - 02 - jQuery.fn.extend 与 jQuery.extend
参考资料:【深入浅出jQuery】源码浅析--整体架构,备用地址:chokcoco/jQuery-。
extend 方法在 jQuery 中是一个很重要的方法。jQuery 内部用它来拓展静态方法或者实例方法,也是开发 jQuery 插件必须要用到的方法。但是,在内部,是存在 jQuery.fn.extend 与 jQuery.extend 两个 extend 方法的,而区分这两个方法是理解 jQuery 的很关键的一部分。先看结论:
1)jQuery.extend(object) 为拓展 jQuery 类本身, 为类添加新的静态方法;
2)jQuery.fn.extend(object) 给 jQuery 实例添加方法,即通过 extend 添加的新方法,实例化的jQuery 对象都可以使用,因为这是挂载在 jQuery.fn 上的方法(前一篇提到, jQuery.fn = jQuery.prototype)。
即:jQuery.extend() 拓展的静态方法,我们可以直接通过 $.xxx() 来调用,比如 $.each() 用来遍历数组;
而 jQuery.fn.extend() 拓展的方法,需要使用 $('xxx').yyy() 调用。
下面是源码:
- // 扩展合并函数
- // 合并两个或更多对象的属性到第一个对象中,jQuery 后续的大部分功能都通过该函数扩展
- // 虽然实现方式一样,但是要注意区分用法的不一样,那么为什么两个方法指向同一个函数实现,但是却实现不同的功能呢,
- // 阅读源码就能发现这归功于 this 的强大力量
- // 如果传入两个或多个对象,所有对象的属性会被添加到第一个对象 target
- // 如果只传入一个对象,则将对象的属性添加到 jQuery 对象中,也就是添加静态方法
- // 用这种方式,我们可以为 jQuery 命名空间增加新的方法,可以用于编写 jQuery 插件
- // 如果不想改变传入的对象,可以传入一个空对象:$.extend({}, object1, object2);
- // 默认合并操作是不迭代的,即便 target 的某个属性是对象或属性,也会被完全覆盖而不是合并
- // 如果第一个参数是 true,则是深拷贝
- // 从 object 原型继承的属性会被拷贝,值为 undefined 的属性不会被拷贝
- // 因为性能原因,JavaScript 自带类型的属性不会合并
- jQuery.extend = jQuery.fn.extend = function () {
- var src, copyIsArray, copy, name, options, clone,
- target = arguments[0] || {},
- i = 1,
- length = arguments.length,
- deep = false;
- // Handle a deep copy situation
- // target 是传入的第一个参数
- // 如果第一个参数是布尔类型,则表示是否要深递归,
- if (typeof target === "boolean") {
- deep = target;
- target = arguments[1] || {};
- // skip the boolean and the target
- // 如果传了类型为 boolean 的第一个参数,i 则从 2 开始
- 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
- // 如果参数的长度为 1 ,表示是 jQuery 静态方法
- if (length === i) {
- //此时的this:如果外部调用的是jQuery.extend方法,则this指jQuery类,扩展到jQuery类上
- //而如果是jQuery.fn.extend方法则this指jQuery原型,扩展到jQuery的原型上
- target = this;
- --i;
- }
- // 可以传入多个复制源
- // i 是从 1或2 开始的
- for (; i < length; i++) {
- // Only deal with non-null/undefined values
- // 将每个源的属性全部复制到 target 上
- if ((options = arguments[i]) != null) {
- // Extend the base object
- for (name in options) {
- // src 是源(即本身)的值
- // copy 是即将要复制过去的值
- src = target[name];
- copy = options[name];
- // Prevent never-ending loop
- // 防止有环,例如 extend(true, target, {'target':target});
- if (target === copy) {
- continue;
- }
- // Recurse if we're merging plain objects or arrays
- // 这里是递归调用,最终都会到下面的 else if 分支
- // jQuery.isPlainObject 用于测试是否为纯粹的对象
- // 纯粹的对象指的是 通过 "{}" 或者 "new Object" 创建的
- // 如果是深复制
- 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
- // 返回新的 target
- // 如果 i < length ,是直接返回没经过处理的 target,也就是 arguments[0]
- // 也就是如果不传需要覆盖的源,调用 $.extend 其实是增加 jQuery 的静态方法
- return target;
- };
jQuery 源码学习 - 02 - jQuery.fn.extend 与 jQuery.extend的更多相关文章
- jquery源码学习笔记三:jQuery工厂剖析
jquery源码学习笔记二:jQuery工厂 jquery源码学习笔记一:总体结构 上两篇说过,query的核心是一个jQuery工厂.其代码如下 function( window, noGlobal ...
- jquery源码学习(一)——jquery结构概述以及如何合适的暴露全局变量
jQuery 源码学习是对js的能力提升很有帮助的一个方法,废话不说,我们来开始学习啦 我们学习的源码是jquery-2.0.3已经不支持IE6,7,8了,因为可以少学很多hack和兼容的方法. jq ...
- jquery 源码学习(四)构造jQuery对象-工具函数
jQuery源码分析-03构造jQuery对象-工具函数,需要的朋友可以参考下. 作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 声明:本文为原 ...
- jquery 源码学习(一)
从上边的注释看,jQuery的源码结构相当清晰.条理,不像代码那般晦涩和让人纠结 1. 总体架构 1.1 自调用匿名函数 self-invoking anonymous function 打开jQ ...
- jquery 源码学习(*)
最近在做日志统计程序,发现对方的程序是在Jquery基础上进行开发的,而公司的网站的框架是prototype.而且我也早就想了解一下Jquery源码,故决定研究Jquery源码,模拟它的方法 Jq ...
- jQuery源码学习扒一扒jQuery对象初使化
神奇的jQuery可以这样玩jQuery("#id").css()或 jQuery("#id").html() 这么玩jQuery("#id" ...
- jQuery源码学习笔记一
学习jQuery源码,我主要是通过妙味视频上学习的.这里将所有的源码分析,还有一些自己弄懂过程中的方法及示例整理出来,供大家参考. 我用的jquery v2.0.3版本. var rootjQuery ...
- jquery源码学习笔记二:jQuery工厂
笔记一里记录,jQuery的总体结构如下: (function( global, factory ) { //调用factory(工厂)生成jQuery实例 factory( global ); }( ...
- jquery 源码学习(三)
jQuery源码分析-03构造jQuery对象-源码结构和核心函数,需要的朋友可以参考下. 作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 毕竟 ...
随机推荐
- python学习笔记--数据类型和变量总结
1.数据类型 字符串 数字 列表 元祖 字典 2.可变不可变划分 可变:列表,字典 不可变:字符串,数字,元祖 举例:字符串,通过id查看字符串变量在内存中的地址.两次存的值不一样,这就说明了内存重新 ...
- 自己做的板子,电脑识别不出下载口(micro-usb),程序无法烧入
前几天画了一块cortex-A5的底板,出现一个问题,就是通过micro-usb与电脑连接之后,电脑无法识别出来,这就导致程序无法通过micro-usb烧入进去,经过仔细检查硬件,发现第一,元器件都没 ...
- setTimeout()执行时序
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...
- Angular ng-container ng-template 用法
ng-container本身不创建任何html代码,相当于一个容器. <ng-container *ngFor="let item of dataSource;let i=index& ...
- 18)C++对C的增强
在C++中所有的变量都必须有类型,但是在C语言中没有这个要求,C语言中的默认类型在C++中不合法, #include<stdio.h> f() { ; } int main() { int ...
- Android之布局LinearLayout
1.weight属性用法 主要用于view对象屏幕适配比例 如下图,左边是等比例,右边是1:2比例 实现代码: <LinearLayout xmlns:android="http:// ...
- Cobbler_自动装系统
Cobbler —自动装系统的操作步骤 Cobbler是一款自动化操作系统安装的实现,与PXE安装系统的区别就是可以同时部署多个版本的系统,而PXE只能选择一种系统. Cobbler 的安装 # 在一 ...
- 4418开发板Android源码整体&单独编译
内核缺省文件配置之后,Android 目录,运行一键编译脚本“build_android.sh”,如下图所示.注意:本篇文章基于iTOP-4418开发板,编译 Android 必须保证给 Ubuntu ...
- 三十七、www服务nginx进阶
六.查看nginx默认首页和目录:如下,可以看到,默认的目录是html,首页是index.html [root@djw1 conf]# grep html nginx.conf ...
- Linux的基础知识
什么是操作系统? 操作系统是人与计算机的中介. 操作系统是干什么的? 控制所有资源{硬件资源和软件资源(驱动,应用软件)} 常用的操作系统:Unix Windows Linux Linux的哲学思想: ...