参考资料:【深入浅出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() 调用。

  下面是源码:

  1. // 扩展合并函数
  2. // 合并两个或更多对象的属性到第一个对象中,jQuery 后续的大部分功能都通过该函数扩展
  3. // 虽然实现方式一样,但是要注意区分用法的不一样,那么为什么两个方法指向同一个函数实现,但是却实现不同的功能呢,
  4. // 阅读源码就能发现这归功于 this 的强大力量
  5. // 如果传入两个或多个对象,所有对象的属性会被添加到第一个对象 target
  6. // 如果只传入一个对象,则将对象的属性添加到 jQuery 对象中,也就是添加静态方法
  7. // 用这种方式,我们可以为 jQuery 命名空间增加新的方法,可以用于编写 jQuery 插件
  8. // 如果不想改变传入的对象,可以传入一个空对象:$.extend({}, object1, object2);
  9. // 默认合并操作是不迭代的,即便 target 的某个属性是对象或属性,也会被完全覆盖而不是合并
  10. // 如果第一个参数是 true,则是深拷贝
  11. // 从 object 原型继承的属性会被拷贝,值为 undefined 的属性不会被拷贝
  12. // 因为性能原因,JavaScript 自带类型的属性不会合并
  13. jQuery.extend = jQuery.fn.extend = function () {
  14. var src, copyIsArray, copy, name, options, clone,
  15. target = arguments[0] || {},
  16. i = 1,
  17. length = arguments.length,
  18. deep = false;
  19.  
  20. // Handle a deep copy situation
  21. // target 是传入的第一个参数
  22. // 如果第一个参数是布尔类型,则表示是否要深递归,
  23. if (typeof target === "boolean") {
  24. deep = target;
  25. target = arguments[1] || {};
  26. // skip the boolean and the target
  27. // 如果传了类型为 boolean 的第一个参数,i 则从 2 开始
  28. i = 2;
  29. }
  30.  
  31. // Handle case when target is a string or something (possible in deep copy)
  32. // 如果传入的第一个参数是 字符串或者其他
  33. if (typeof target !== "object" && !jQuery.isFunction(target)) {
  34. target = {};
  35. }
  36.  
  37. // extend jQuery itself if only one argument is passed
  38. // 如果参数的长度为 1 ,表示是 jQuery 静态方法
  39. if (length === i) {
  40. //此时的this:如果外部调用的是jQuery.extend方法,则this指jQuery类,扩展到jQuery类上
  41. //而如果是jQuery.fn.extend方法则this指jQuery原型,扩展到jQuery的原型上
  42. target = this;
  43. --i;
  44. }
  45.  
  46. // 可以传入多个复制源
  47. // i 是从 1或2 开始的
  48. for (; i < length; i++) {
  49. // Only deal with non-null/undefined values
  50. // 将每个源的属性全部复制到 target 上
  51. if ((options = arguments[i]) != null) {
  52. // Extend the base object
  53. for (name in options) {
  54. // src 是源(即本身)的值
  55. // copy 是即将要复制过去的值
  56. src = target[name];
  57. copy = options[name];
  58.  
  59. // Prevent never-ending loop
  60. // 防止有环,例如 extend(true, target, {'target':target});
  61. if (target === copy) {
  62. continue;
  63. }
  64.  
  65. // Recurse if we're merging plain objects or arrays
  66. // 这里是递归调用,最终都会到下面的 else if 分支
  67. // jQuery.isPlainObject 用于测试是否为纯粹的对象
  68. // 纯粹的对象指的是 通过 "{}" 或者 "new Object" 创建的
  69. // 如果是深复制
  70. if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
  71. // 数组
  72. if (copyIsArray) {
  73. copyIsArray = false;
  74. clone = src && jQuery.isArray(src) ? src : [];
  75. } else {
  76. clone = src && jQuery.isPlainObject(src) ? src : {};
  77. }
  78.  
  79. // Never move original objects, clone them
  80. // 递归
  81. target[name] = jQuery.extend(deep, clone, copy);
  82.  
  83. // Don't bring in undefined values
  84. // 最终都会到这条分支
  85. // 简单的值覆盖
  86. } else if (copy !== undefined) {
  87. target[name] = copy;
  88. }
  89. }
  90. }
  91. }
  92.  
  93. // Return the modified object
  94. // 返回新的 target
  95. // 如果 i < length ,是直接返回没经过处理的 target,也就是 arguments[0]
  96. // 也就是如果不传需要覆盖的源,调用 $.extend 其实是增加 jQuery 的静态方法
  97. return target;
  98. };

jQuery 源码学习 - 02 - jQuery.fn.extend 与 jQuery.extend的更多相关文章

  1. jquery源码学习笔记三:jQuery工厂剖析

    jquery源码学习笔记二:jQuery工厂 jquery源码学习笔记一:总体结构 上两篇说过,query的核心是一个jQuery工厂.其代码如下 function( window, noGlobal ...

  2. jquery源码学习(一)——jquery结构概述以及如何合适的暴露全局变量

    jQuery 源码学习是对js的能力提升很有帮助的一个方法,废话不说,我们来开始学习啦 我们学习的源码是jquery-2.0.3已经不支持IE6,7,8了,因为可以少学很多hack和兼容的方法. jq ...

  3. jquery 源码学习(四)构造jQuery对象-工具函数

    jQuery源码分析-03构造jQuery对象-工具函数,需要的朋友可以参考下.   作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 声明:本文为原 ...

  4. jquery 源码学习(一)

    从上边的注释看,jQuery的源码结构相当清晰.条理,不像代码那般晦涩和让人纠结   1. 总体架构 1.1 自调用匿名函数 self-invoking anonymous function 打开jQ ...

  5. jquery 源码学习(*)

    最近在做日志统计程序,发现对方的程序是在Jquery基础上进行开发的,而公司的网站的框架是prototype.而且我也早就想了解一下Jquery源码,故决定研究Jquery源码,模拟它的方法   Jq ...

  6. jQuery源码学习扒一扒jQuery对象初使化

    神奇的jQuery可以这样玩jQuery("#id").css()或 jQuery("#id").html() 这么玩jQuery("#id" ...

  7. jQuery源码学习笔记一

    学习jQuery源码,我主要是通过妙味视频上学习的.这里将所有的源码分析,还有一些自己弄懂过程中的方法及示例整理出来,供大家参考. 我用的jquery v2.0.3版本. var rootjQuery ...

  8. jquery源码学习笔记二:jQuery工厂

    笔记一里记录,jQuery的总体结构如下: (function( global, factory ) { //调用factory(工厂)生成jQuery实例 factory( global ); }( ...

  9. jquery 源码学习(三)

    jQuery源码分析-03构造jQuery对象-源码结构和核心函数,需要的朋友可以参考下.   作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 毕竟 ...

随机推荐

  1. python学习笔记--数据类型和变量总结

    1.数据类型 字符串 数字 列表 元祖 字典 2.可变不可变划分 可变:列表,字典 不可变:字符串,数字,元祖 举例:字符串,通过id查看字符串变量在内存中的地址.两次存的值不一样,这就说明了内存重新 ...

  2. 自己做的板子,电脑识别不出下载口(micro-usb),程序无法烧入

    前几天画了一块cortex-A5的底板,出现一个问题,就是通过micro-usb与电脑连接之后,电脑无法识别出来,这就导致程序无法通过micro-usb烧入进去,经过仔细检查硬件,发现第一,元器件都没 ...

  3. setTimeout()执行时序

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...

  4. Angular ng-container ng-template 用法

    ng-container本身不创建任何html代码,相当于一个容器. <ng-container *ngFor="let item of dataSource;let i=index& ...

  5. 18)C++对C的增强

    在C++中所有的变量都必须有类型,但是在C语言中没有这个要求,C语言中的默认类型在C++中不合法, #include<stdio.h> f() { ; } int main() { int ...

  6. Android之布局LinearLayout

    1.weight属性用法 主要用于view对象屏幕适配比例 如下图,左边是等比例,右边是1:2比例 实现代码: <LinearLayout xmlns:android="http:// ...

  7. Cobbler_自动装系统

    Cobbler —自动装系统的操作步骤 Cobbler是一款自动化操作系统安装的实现,与PXE安装系统的区别就是可以同时部署多个版本的系统,而PXE只能选择一种系统. Cobbler 的安装 # 在一 ...

  8. 4418开发板Android源码整体&单独编译

    内核缺省文件配置之后,Android 目录,运行一键编译脚本“build_android.sh”,如下图所示.注意:本篇文章基于iTOP-4418开发板,编译 Android 必须保证给 Ubuntu ...

  9. 三十七、www服务nginx进阶

    六.查看nginx默认首页和目录:如下,可以看到,默认的目录是html,首页是index.html [root@djw1 conf]# grep html nginx.conf            ...

  10. Linux的基础知识

    什么是操作系统? 操作系统是人与计算机的中介. 操作系统是干什么的? 控制所有资源{硬件资源和软件资源(驱动,应用软件)} 常用的操作系统:Unix Windows Linux Linux的哲学思想: ...