jQuery 的 API 手册中,extend 方法挂载在 jQuery 和 jQuery.fn 两个不一样的对象上,但在 jQuery 内部代码实现的是相同的,只是功能各不相同。css
先看看官方给出的解释:json
jQuery.extend Merge the contents of two or more objects together into the first object. 把两个或者多个对象合并到第一个对象当中;数组
jQuery.fn.extend Merge the contents of an object onto the jQuery prototype to provide new jQuery instance methods. 把对象挂载到 jQuery 的 prototype 上以扩展一个新的 jQuery 实例方法 。ide
虽然官方对 jQuery.extend 的扩展方法功能只字未提,可是它也一样具备扩展 jQuery 类方法 的功能。函数
首先,我先来介绍一下 extend 函数在 合并对象 方面的用法。工具
jQuery.extend(target [, object1] [, objectN])
合并 object1 ... objectN 到 target 对象,若是只有一个参数,则该 target 对象会被合并到 jQuery 对象中。this
var obj1 = { name: 'Tom', age: 21 } var obj2 = { name: 'Jerry', sex: 'boy' } $.extend(obj1, obj2); // {name: "Jerry", age: 21, sex: "boy"} obj1 // {name: "Jerry", age: 21, sex: "boy"} obj2 // {name: "Jerry", sex: "boy"}
上述代码展现的是将 obj2 对象合并到 obj1 对象中,这种方法会 改变 obj1 对象的结构。若是你 不想改变 合并目标对象的结构,你能够这么作。prototype
var obj1 = { name: 'Tom', age: 21 } var obj2 = { name: 'Jerry', sex: 'boy' } $.extend({}, obj1, obj2); // { name: "Jerry", age: 21, sex: "boy" } obj1 // { name: "Tom", age: 21 } obj2 // { name: "Jerry", sex: "boy" }
jQuery.extend([deep], target, object1 [, objectN])
和上面的讲述的不一样的是,该方法多了一个类型为 boolean 的 [deep] 传参,当其为 true 时,将 object1 , objectN 深度复制 后合并到 target 中。code
首先,咱们理解一下什么叫作 深度复制 。看看其和 浅度复制 有什么区别。对象
var obj1 = { name: "John", location: { city: "Boston", county: "USA" } } var obj2 = { last: "Resig", location: { state: "MA", county: "China" } } $.extend(false, {}, obj1, obj2); // { name: "John", last: "Resig", location: { state: "MA", county: "China" }} $.extend(true, {}, obj1, obj2); // { name: "John", last: "Resig", location: { city: "Boston", state: "MA", county: "China" }}
因而可知,执行 深度复制 会递归遍历每一个对象中含有复杂对象(如:数组、函数、json对象等)的属性值进行复制,并且 浅度复制 便不会这么作。
上述的 extend 方法中的 target 参数是能够省略的。若是省略了,则该方法就只能传入一个 object 参数,该方法功能是将该 object 合并到调用 extend 方法的对象中。
咱们一般会使用这种方式来对 jQuer进行一些方法上的扩展。
jQurey 提供了两种方法扩张方式,分别为jQuery.fn.extend(object)
和jQuery.extend(object)
.
想要搞清楚两种扩展方式之间的区别的话,先要了解什么是jQuery.fn
.
本猿参考了 jQuery 的源码,发现其中玄机:
jQuery.fn = jQuery.prototype = { init: function(selector, context) { // ... }; }
jQuery.fn = jQuery.prototype
这句代码明确指出jQuery.fn
指代的就是 jQuery 的原型。
其次,咱们要引入两个概念 类方法 和 实例方法 。
类方法 是直接可使用类引用,不须要实例化就可使用的方法。通常在项目中 类方法 都是被设置为工具类使用;
实例方法 必须先建立实例,而后才能经过实例调用该 实例方法 。
jQuery
能够看作是这个封装得很是好的类,而咱们可使用jQuery选择器
来建立 jQuery 的实例。好比:使 id 选择器$('#btn')
来建立一个实例。
jQuery.extend(object)
至关于对 类方法 的扩展。
jQuery.extend({ /* 返回两个元素中较小的值 */ min: function(a, b) { return a < b ? a : b; }, /* 返回两个元素中较大的值 */ max: function(a, b) { return a > b ? a : b; } }); jQuery.min(2, 3); // 2 jQuery.max(4, 5); // 5
jQuery.fn.extend(object)
是对jQuery.prototype
上的扩展。
jQuery.fn.extend = jQuery.prototype.extend
这种方式至关对 实例方法 的扩展。
举个栗子:
开发一个简单的小功能,使用该方法可使选定元素内的文字变红。
$.fn.extend({ setRed: function() { $(this).css("color", "red"); } }); $('.tip').setRed();
$(".tip")
建立了一个jQuery实例
,经过它能够调用成员方法setRed
.
上述代码能够实现预想的扩展,但最好返回this
以知足 jQuery 链式操做 的须要。
改良以后,代码以下:
$.fn.extend({ red: function() { return $(this).css("color", "red"); } });