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 相关文章推荐
又一个小巧的图片预加载类
May 05 Javascript
javascript脚本调试方法小结
Nov 24 Javascript
jquery+json实现的搜索加分页效果
Mar 31 Javascript
javascript特殊用法示例介绍
Nov 29 Javascript
jQuery实现的动态伸缩导航菜单实例
May 07 Javascript
javascript每日必学之继承
Feb 23 Javascript
BootStrap按钮标签及基本样式
Nov 23 Javascript
详解在Vue中通过自定义指令获取dom元素
Mar 04 Javascript
Vue官方推荐AJAX组件axios.js使用方法详解与API
Oct 09 Javascript
解决ele ui 表格表头太长问题的实现
Nov 13 Javascript
详解Java中String JSONObject JSONArray List转换
Nov 13 Javascript
JavaScript 对象创建的3种方法
Nov 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
上海牌131型七灯四波段四喇叭一级收音机
2021/03/02 无线电
php网站被挂木马后的修复方法总结
2014/11/06 PHP
php短址转换实现方法
2015/02/25 PHP
PHP内部实现打乱字符串顺序函数str_shuffle的方法
2019/02/14 PHP
解决iframe的frameborder在chrome/ff/ie下的差异
2010/08/12 Javascript
div层的移动及性能优化
2010/11/16 Javascript
js动态为代码着色显示行号
2013/05/29 Javascript
js改变img标签的src属性在IE下没反应的解决方法
2013/07/23 Javascript
js获取事件源及触发该事件的对象
2013/10/24 Javascript
利用jq让你的div居中的好方法分享
2013/11/21 Javascript
13个PHP函数超实用
2015/10/21 Javascript
jQuery实现Email邮箱地址自动补全功能代码
2015/11/03 Javascript
jQuery中show与hide方法用法示例
2016/09/16 Javascript
AngularJs $parse、$eval和$observe、$watch详解
2016/09/21 Javascript
Bootstrap幻灯片轮播图支持触屏左右手势滑动的实现方法
2016/10/13 Javascript
JavaScript 基础表单验证示例(纯Js实现)
2017/07/20 Javascript
详解如何去除vue项目中的#——History模式
2017/10/13 Javascript
dropload.js插件下拉刷新和上拉加载使用详解
2017/10/20 Javascript
使用VueRouter的addRoutes方法实现动态添加用户的权限路由
2019/06/03 Javascript
axios封装与传参示例详解
2020/10/18 Javascript
[00:32]2018DOTA2亚洲邀请赛VGJ.T出场
2018/04/03 DOTA
[02:02]特效爆炸!DOTA2珍宝之瓶待你开启
2018/08/21 DOTA
Python基于Tkinter实现的记事本实例
2015/06/17 Python
Python安装模块的常见问题及解决方法
2018/02/05 Python
python+logging+yaml实现日志分割
2019/07/22 Python
使用python+whoosh实现全文检索
2019/12/09 Python
如何用Python提取10000份log中的产品信息
2021/01/14 Python
html5+svg学习指南之SVG基础知识
2014/12/17 HTML / CSS
英国安全产品购物网站:The Safe Shop
2017/03/20 全球购物
荷兰网上买鞋:MooieSchoenen.nl
2017/09/12 全球购物
美国领先的奢侈手表在线零售商:WatchMaxx
2017/12/17 全球购物
办公室综合文员岗位职责范本
2014/02/13 职场文书
医学专业毕业生推荐信
2014/07/12 职场文书
职工小家建设活动方案
2014/08/25 职场文书
班级班风口号大全
2015/12/25 职场文书
css3中2D转换之有趣的transform形变效果
2022/02/24 HTML / CSS