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 相关文章推荐
jQuery live
May 15 Javascript
基于jquery的cookie的用法
Jan 10 Javascript
Node.js入门教程:在windows和Linux上安装配置Node.js图文教程
Aug 14 Javascript
jQuery前端框架easyui使用Dialog时bug处理
Dec 05 Javascript
javascript转换静态图片,增加粒子动画效果
May 28 Javascript
AngularJs入门教程之环境搭建+创建应用示例
Nov 01 Javascript
AngularJS中watch监听用法分析
Nov 04 Javascript
vue多种弹框的弹出形式的示例代码
Sep 18 Javascript
小程序实现列表点赞功能
Nov 02 Javascript
ES6数组与对象的解构赋值详解
Jun 14 Javascript
详解nuxt 微信公众号支付遇到的问题与解决
Aug 26 Javascript
vue canvas绘制矩形并解决由clearRec带来的闪屏问题
Sep 02 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
Cannot modify header information错误解决方法
2008/10/08 PHP
php入门学习知识点一 PHP与MYSql连接与查询
2011/07/14 PHP
如何通过PHP实现Des加密算法代码实例
2020/05/09 PHP
用jQuery实现检测浏览器及版本的脚本代码
2008/01/22 Javascript
raphael.js绘制中国地图 地图绘制方法
2014/02/12 Javascript
js跨域访问示例(客户端/服务端)
2014/05/19 Javascript
JavaScript使用cookie记录临时访客信息的方法
2015/04/07 Javascript
jQuery实现可兼容IE6的滚动监听功能
2017/09/20 jQuery
不使用 JS 匿名函数理由
2017/11/17 Javascript
详解vue-cli3使用
2018/08/14 Javascript
用VsCode编辑TypeScript的实现方法
2020/05/07 Javascript
微信小程序完美解决scroll-view高度自适应问题的方法
2020/08/08 Javascript
Postman参数化实现过程及原理解析
2020/08/13 Javascript
vue切换菜单取消未完成接口请求的案例
2020/11/13 Javascript
python实现分析apache和nginx日志文件并输出访客ip列表的方法
2015/04/04 Python
python比较2个xml内容的方法
2015/05/11 Python
Python实现批量修改文件名实例
2015/07/08 Python
实例解析Python的Twisted框架中Deferred对象的用法
2016/05/25 Python
【Python】Python的urllib模块、urllib2模块批量进行网页下载文件
2016/11/19 Python
Python3爬虫爬取英雄联盟高清桌面壁纸功能示例【基于Scrapy框架】
2018/12/05 Python
python对视频画框标记后保存的方法
2018/12/07 Python
python 视频逐帧保存为图片的完整实例
2019/12/10 Python
用python爬取历史天气数据的方法示例
2019/12/30 Python
np.random.seed() 的使用详解
2020/01/14 Python
Python3使用xlrd、xlwt处理Excel方法数据
2020/02/28 Python
matplotlib基础绘图命令之imshow的使用
2020/08/13 Python
css3实现书本翻页效果的示例代码
2021/03/08 HTML / CSS
业务部门经理岗位职责
2014/02/23 职场文书
廉洁自律承诺书
2014/03/27 职场文书
《金孔雀轻轻跳》教学反思
2014/04/20 职场文书
营销与策划专业求职信
2014/06/20 职场文书
开展创先争优活动总结
2014/08/28 职场文书
电力工程合作意向书
2015/05/11 职场文书
工作违纪的检讨书范文
2019/07/09 职场文书
golang日志包logger的用法详解
2021/05/05 Golang
Python实现批量自动整理文件
2022/03/16 Python