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 相关文章推荐
js中的数组Array定义与sort方法使用示例
Aug 29 Javascript
jQuery的animate函数实现图文切换动画效果
May 03 Javascript
javascript实现显示和隐藏div方法汇总
Aug 14 Javascript
AngularJS 实现按需异步加载实例代码
Oct 18 Javascript
基于JavaScript实现TAB标签效果
Jan 12 Javascript
jquery ajax分页插件的简单实现
Jan 27 Javascript
浅谈window.onbeforeunload() 事件调用ajax
Jun 29 Javascript
js实现倒计时关键代码
May 05 Javascript
Vue利用canvas实现移动端手写板的方法
May 03 Javascript
使用vue2.6实现抖音【时间轮盘】屏保效果附源码
Apr 24 Javascript
vue实现在v-html的html字符串中绑定事件
Oct 28 Javascript
解决qrcode.js生成二维码时必须定义一个空div的问题
Jul 09 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
2006/12/14 PHP
php的4种常用运行方式详解
2016/12/22 PHP
javascript读取xml
2006/11/04 Javascript
AJAX 网页保留浏览器前进后退等功能
2011/02/12 Javascript
在JS中如何调用JSP中的变量
2014/01/22 Javascript
用nodejs实现PHP的print_r函数代码
2014/03/14 NodeJs
基于JQuery制作可编辑的表格特效
2014/12/23 Javascript
JavaScript设计模式之单件模式介绍
2014/12/28 Javascript
JavaScript控制两个列表框listbox左右交换数据的方法
2015/03/18 Javascript
AngularJS入门教程之XHR和依赖注入详解
2016/08/18 Javascript
jQuery+json实现动态创建复杂表格table的方法
2016/10/25 Javascript
JavaScript简单拖拽效果(1)
2017/05/17 Javascript
JS仿淘宝搜索框用户输入事件的实现
2017/06/19 Javascript
React-Native 组件之 Modal的使用详解
2017/08/08 Javascript
JS模拟超市简易收银台小程序代码解析
2017/08/18 Javascript
利用d3.js制作连线动画图与编辑器的方法实例
2019/09/05 Javascript
JavaScript实现省市联动效果
2019/11/22 Javascript
JS原型对象操作实例分析
2020/06/06 Javascript
详解JavaScript中的Object.is()与&quot;===&quot;运算符总结
2020/06/17 Javascript
Python写的贪吃蛇游戏例子
2014/06/16 Python
Python最火、R极具潜力 2017机器学习调查报告
2017/12/11 Python
Python参数解析模块sys、getopt、argparse使用与对比分析
2019/04/02 Python
Python 获取 datax 执行结果保存到数据库的方法
2019/07/11 Python
django列表筛选功能的实现代码
2020/03/27 Python
python中什么是面向对象
2020/06/11 Python
使用npy转image图像并保存的实例
2020/07/01 Python
ProBikeKit英国:在线公路自行车之家
2017/02/10 全球购物
Spartoo美国:欧洲排名第一的在线时装零售商
2019/12/12 全球购物
六查六看剖析材料
2014/02/15 职场文书
乒乓球兴趣小组活动总结
2014/07/08 职场文书
2014年重阳节老干部座谈会局领导发言稿
2014/09/25 职场文书
党的群众路线教育实践活动心得体会范文
2014/11/05 职场文书
毕业生政审意见范文
2015/06/04 职场文书
委托收款证明
2015/06/23 职场文书
Python中Permission denied的解决方案
2021/04/02 Python
MySQL 外键约束和表关系相关总结
2021/06/20 MySQL