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源码学习javascript(一)
Dec 27 Javascript
js 走马灯简单实例
Nov 21 Javascript
js中substring和substr的定义和用法
May 05 Javascript
JavaScript获取对象在页面中位置坐标的方法
Feb 03 Javascript
JQuery 设置checkbox值二次无效的解决方法
Jul 22 Javascript
基于bootstrap风格的弹框插件
Dec 28 Javascript
使用electron实现百度网盘悬浮窗口功能的示例代码
Oct 24 Javascript
基于Three.js实现360度全景图片
Dec 30 Javascript
详解vue微信网页授权最终解决方案
Jun 16 Javascript
node省市区三级数据性能测评实例分析
Nov 06 Javascript
微信小程序实现音频文件播放进度的实例代码
Mar 02 Javascript
Vue仿百度搜索功能
Dec 28 Vue.js
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注入点构造代码
2008/06/14 PHP
PHP mb_convert_encoding 获取字符串编码类型实现代码
2009/04/26 PHP
记录PHP错误日志 display_errors与log_errors的区别
2012/10/09 PHP
YII2框架中添加自定义模块的方法实例分析
2020/03/18 PHP
jquery imgareaselect 使用利用js与程序结合实现图片剪切
2009/07/30 Javascript
Web Inspector:关于在 Sublime Text 中调试Js的介绍
2013/04/18 Javascript
jQuery实现首页顶部可伸缩广告特效代码
2015/04/15 Javascript
SublimeText自带格式化代码功能之reindent
2015/12/27 Javascript
jQuery实现的分子运动小球碰撞效果
2016/01/27 Javascript
原生js三级联动的简单实现代码
2016/06/07 Javascript
bootstrap table表格插件使用详解
2017/05/08 Javascript
vue2.0中vue-cli实现全选、单选计算总价格的实例代码
2017/07/18 Javascript
centos 上快速搭建ghost博客方法分享
2018/05/23 Javascript
AngularJS中ng-options实现下拉列表的数据绑定方法
2018/08/13 Javascript
element-ui组件中input等的change事件中传递自定义参数
2019/05/22 Javascript
详解ng-alain动态表单SF表单项设置必填和正则校验
2019/06/11 Javascript
JS document内容及样式操作完整示例
2020/01/14 Javascript
vue.js使用v-model实现父子组件间的双向通信示例
2020/02/05 Javascript
vue实现匀速轮播效果
2020/06/29 Javascript
详解React 条件渲染
2020/07/08 Javascript
vue任意关系组件通信与跨组件监听状态vue-communication
2020/10/18 Javascript
Python获取文件ssdeep值的方法
2014/10/05 Python
python自动12306抢票软件实现代码
2018/02/24 Python
Python二进制串转换为通用字符串的方法
2018/07/23 Python
用Python将mysql数据导出成json的方法
2018/08/21 Python
解决pycharm 远程调试 上传 helpers 卡住的问题
2019/06/27 Python
python的pyecharts绘制各种图表详细(附代码)
2019/11/11 Python
Python读取VOC中的xml目标框实例
2020/03/10 Python
Python调用OpenCV实现图像平滑代码实例
2020/06/19 Python
python opencv pytesseract 验证码识别的实现
2020/08/28 Python
PyQt 如何创建自定义QWidget
2021/03/24 Python
远程研修随笔感言
2014/02/10 职场文书
中式结婚主持词
2014/03/14 职场文书
中秋晚会活动方案
2014/08/31 职场文书
浅谈Python numpy创建空数组的问题
2021/05/25 Python
MySQL 数据类型详情
2021/11/11 MySQL