jQuery中extend函数详解


Posted in Javascript onFebruary 13, 2015

在jQuery的API手册中,我们看到,extend实际上是挂载在jQuery和jQuery.fn上的两个不同方法,尽管在jQuery内部jQuery.extend()和jQuery.fn.extend()是用相同的代码实现的,但是它们的功能却不太一样。来看一下 官方API对extend 的解释:

代码如下:

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实例方法)

我们知道,jQuery有静态方法和实例方法之分, 那么jQuery.extend()和jQuery.fn.extend()的第一个区别就是一个用来扩展静态方法,一个用来扩展实例方法。用法如下:

jQuery.extend({

sayhello: function (){

console.log( "Hello,This is jQuery Library" );

}

})

$.sayhello(); //Hello, This is jQuery Library

jQuery.fn.extend({

check: function () {

return this .each( function () {

this .checked = true ;

});

},

uncheck: function () {

return this .each( function () {

this .checked = false ;

});

}

})

$( "input[type='checkbox']" ).check(); //所有的checkbox都会被选择

注意两种调用插件的方式,一种是直接用$调用,另外一种是用$()调用,另外jQuery.extend()接收多个对象作为参数,如果只有一个参数,则把这个对象的属性方法附加到jQuery上,如果含有多个参数,则把后面的对象的属性和方法附加到第一个对象上。jQuery extend的实现源码:

jQuery.extend = jQuery.fn.extend = function () {

var options, name, src, copy, copyIsArray, clone,

target = arguments[0] || {},

i = 1,

length = arguments.length,

deep = false ;

// Handle a deep copy situation

if ( typeof target === "boolean" ) {

deep = target;

target = arguments[1] || {};

// skip the boolean and the target

i = 2;

}

if ( typeof target !== "object" && !jQuery.isFunction(target) ) {

target = {};

}

if ( length === i ) {

target = this ;

--i;

}

for ( ; i < length; i++ ) {

if ( (options = arguments[ i ]) != null ) {

// Extend the base object

for ( name in options ) {

src = target[ name ];

copy = options[ name ];

// Prevent never-ending loop

if ( target === copy ) {

continue ;

}

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;

}

}

}

}

// Return the modified object

return target;

};

很大一堆代码,乍看起来难以理解,其实代码的大部分都是用来实现jQuery.extend()中有多个参数时的对象合并,深度拷贝问题,如果去掉这些功能,让extend只有扩展静态和实例方法的功能,那么代码如下:

jQuery.extend = jQuery.fn.extend = function (obj){

//obj是传递过来扩展到this上的对象

var target= this ;

for ( var name in obj){

//name为对象属性

//copy为属性值

copy=obj[name];

//防止循环调用

if (target === copy) continue ;

//防止附加未定义值

if ( typeof copy === 'undefined' ) continue ;

//赋值

target[name]=copy;

}

return target;

}

下面再来对extend方法进行注释解释:

jQuery.extend = jQuery.fn.extend = function () {

// 定义默认参数和变量

// 对象分为扩展对象和被扩展的对象

//options 代表扩展的对象中的方法

//name 代表扩展对象的方法名

//i 为扩展对象参数起始值

//deep 默认为浅复制

var options, name, src, copy, copyIsArray, clone,

target = arguments[0] || {},

i = 1,

length = arguments.length,

deep = false ;

//对接下来的参数进行处理

if ( typeof target === "boolean" ) {

deep = target;

target = arguments[1] || {};

i = 2;

}

if ( typeof target !== "object" && !jQuery.isFunction(target) ) {

target = {};

}

if ( length === i ) {

target = this ;

--i;

}

//对从i开始的多个参数进行遍历

for ( ; i < length; i++ ) {

// 只处理有定义的值

if ( (options = arguments[ i ]) != null ) {

// 展开扩展对象

for ( name in options ) {

src = target[ name ];

copy = options[ name ];

// 防止循环引用

if ( target === copy ) {

continue ;

}

// 递归处理深拷贝

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 );

// 不处理未定义值

} else if ( copy !== undefined ) {

//给target增加属性或方法

target[ name ] = copy;

}

}

}

}

//返回

return target;

};

弄懂了jQuery扩展的原理,相信以后再也不用为编写jQuery插件而烦恼了。

Javascript 相关文章推荐
有道JavaScript监听浏览器的问题
Jun 23 Javascript
JS 添加网页桌面快捷方式的代码详细整理
Dec 27 Javascript
js,jquery滚动/跳转页面到指定位置的实现思路
Jun 03 Javascript
Jquery对select的增、删、改、查操作
Feb 06 Javascript
JavaScript获取页面中第一个锚定文本的方法
Apr 03 Javascript
jQuery实现提示密码强度的代码
Jul 15 Javascript
网站申请不到支付宝接口、微信接口,免接口收款实现方式几种解决办法
Dec 14 Javascript
AngularJS入门教程之Helloworld示例
Dec 25 Javascript
详细讲解vue2+vuex+axios
May 27 Javascript
Vue二次封装axios为插件使用详解
May 21 Javascript
JavaScript常见事件对象与操作实例总结
Jan 05 Javascript
react native 仿微信聊天室实例代码
Sep 17 Javascript
JavaScript将Web页面内容导出到Word及Excel的方法
Feb 13 #Javascript
javascript上下方向键控制表格行选中并高亮显示的方法
Feb 13 #Javascript
JS+CSS实现可拖拽的漂亮圆角特效弹出层完整实例
Feb 13 #Javascript
jQuery实现DIV层淡入淡出拖动特效的方法
Feb 13 #Javascript
JS实现固定在右下角可展开收缩DIV层的方法
Feb 13 #Javascript
JS仿iGoogle自定义首页模块拖拽特效的方法
Feb 13 #Javascript
JS弹出可拖拽可关闭的div层完整实例
Feb 13 #Javascript
You might like
php中支持多种编码的中文字符串截取函数!
2007/03/20 PHP
ThinkPHP与PHPExcel冲突解决方法
2011/08/08 PHP
使用php将某个目录下面的所有文件罗列出来的方法详解
2013/06/21 PHP
PHP实现微信模拟登陆并给用户发送消息的方法【文字,图片,图文】
2017/06/29 PHP
thinkPHP3.2.3结合Laypage实现的分页功能示例
2018/05/28 PHP
jquery animate图片模向滑动示例代码
2011/01/26 Javascript
打开新窗口关闭当前页面不弹出关闭提示js代码
2013/03/18 Javascript
基于jquery css3实现点击动画弹出表单源码特效
2015/08/31 Javascript
angular源码学习第一篇 setupModuleLoader方法
2016/10/20 Javascript
js实现带缓动动画的导航栏效果
2017/01/16 Javascript
详解微信小程序 wx.uploadFile 的编码坑
2017/01/23 Javascript
JS获取日期的方法实例【昨天,今天,明天,前n天,后n天的日期】
2017/09/28 Javascript
vue 使用ref 让父组件调用子组件的方法
2018/02/08 Javascript
vue中的模态对话框组件实现过程
2018/05/01 Javascript
vue项目中使用AES实现密码加密解密(ECB和CBC两种模式)
2019/08/12 Javascript
vuex存储复杂参数(如对象数组等)刷新数据丢失的解决方法
2019/11/05 Javascript
vue vant Area组件使用详解
2019/12/09 Javascript
Vue列表如何实现滚动到指定位置样式改变效果
2020/05/09 Javascript
谈一谈vue请求数据放在created好还是mounted里好
2020/07/27 Javascript
OpenLayers3实现对地图的基本操作
2020/09/28 Javascript
python检查指定文件是否存在的方法
2015/07/06 Python
python实现获取Ip归属地等信息
2016/08/27 Python
Scrapy的简单使用教程
2017/10/24 Python
python实现淘宝秒杀聚划算抢购自动提醒源码
2020/06/23 Python
用Python将结果保存为xlsx的方法
2019/01/28 Python
django写用户登录判定并跳转制定页面的实例
2019/08/21 Python
详解Pycharm出现out of memory的终极解决方法
2020/03/03 Python
Herve Leger官网:标志性绷带连衣裙等
2018/12/26 全球购物
函授药学自我鉴定
2014/02/07 职场文书
医院信息公开实施方案
2014/05/09 职场文书
文员岗位职责
2015/02/04 职场文书
党支部创先争优公开承诺书
2015/04/30 职场文书
导游词之太原天龙山
2020/01/02 职场文书
Python自然语言处理之切分算法详解
2021/04/25 Python
Spring Data JPA使用JPQL与原生SQL进行查询的操作
2021/06/15 Java/Android
《堡垒之夜》联动《刺客信条》 4月7日正式上线
2022/04/06 其他游戏