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+CSS 实现的超Sexy下拉菜单
Jan 17 Javascript
JS的反射问题
Apr 07 Javascript
15 个 JavaScript Web UI 库
May 19 Javascript
js 表单提交后按钮变灰的实例代码
Aug 16 Javascript
javascript图片相似度算法实现 js实现直方图和向量算法
Jan 14 Javascript
JavaScript格式化日期时间的方法和自定义格式化函数示例
Apr 04 Javascript
JQuery查找子元素find()和遍历集合each的方法总结
Mar 07 Javascript
Javascript实现登录记住用户名和密码功能
Mar 22 Javascript
在JS循环中使用async/await的方法
Oct 12 Javascript
详解基于webpack&amp;gettext的前端多语言方案
Jan 29 Javascript
通过cordova将vue项目打包为webapp的方法
Feb 02 Javascript
jQuery实现每日秒杀商品倒计时功能
Sep 06 jQuery
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中的cookie
2006/11/26 PHP
PHP中HTTP方式下的Gzip压缩传输方法举偶
2007/02/15 PHP
php将session放入memcached的设置方法
2014/02/14 PHP
使用php转义输出HTML到JavaScript
2015/03/27 PHP
laravel实现前后台路由分离的方法
2019/10/13 PHP
PHP使用PhpSpreadsheet操作Excel实例详解
2020/03/26 PHP
网页常用特效代码整理
2006/06/23 Javascript
用JQuery模仿淘宝的图片放大镜显示效果
2011/09/15 Javascript
一看就懂:jsonp详解
2015/06/01 Javascript
深入理解JavaScript程序中内存泄漏
2016/03/17 Javascript
js阻止浏览器默认行为的简单实例
2016/05/15 Javascript
Bootstrap自动适应PC、平板、手机的Bootstrap栅格系统
2016/05/27 Javascript
JS如何设置cookie有效期为当天24点并弹出欢迎登陆界面
2016/08/04 Javascript
利用jquery获取select下拉框的值
2016/11/23 Javascript
学习 NodeJS 第八天:Socket 通讯实例
2016/12/21 NodeJs
详解Angular.js指令中scope类型的几种特殊情况
2017/02/21 Javascript
jQuery滑动到底部加载下一页数据的实例代码
2017/05/22 jQuery
Angularjs实现下拉框联动的示例代码
2017/08/22 Javascript
详解node字体压缩插件font-spider的用法
2018/09/28 Javascript
JavaScript学习笔记之DOM操作实例分析
2019/01/08 Javascript
layui 点击重置按钮, select 并没有被重置的解决方法
2019/09/03 Javascript
[02:17]DOTA2亚洲邀请赛 RAVE战队出场宣传片
2015/02/07 DOTA
Python使用matplotlib的pie函数绘制饼状图功能示例
2018/01/08 Python
python实现共轭梯度法
2019/07/03 Python
python中的列表与元组的使用
2019/08/08 Python
利用OpenCV和Python实现查找图片差异
2019/12/19 Python
pytorch cuda上tensor的定义 以及减少cpu的操作详解
2020/06/23 Python
Python实现数字的格式化输出
2020/08/01 Python
Python 中如何写注释
2020/08/28 Python
解决Python3.8运行tornado项目报NotImplementedError错误
2020/09/02 Python
衰败城市英国官网:Urban Decay英国
2020/04/29 全球购物
创业资金计划书
2014/02/06 职场文书
省级优秀毕业生主要事迹
2014/05/29 职场文书
出生医学证明书
2014/09/15 职场文书
如何理解Vue简单状态管理之store模式
2021/05/15 Vue.js
详解Python类和对象内容
2021/06/22 Python