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 相关文章推荐
重定向实现代码
Nov 20 Javascript
JQuery UI皮肤定制
Jul 27 Javascript
解析javascript系统错误:-1072896658的解决办法
Jul 08 Javascript
JQuery之focus函数使用介绍
Aug 20 Javascript
解决bootstrap中modal遇到Esc键无法关闭页面
Mar 09 Javascript
Jquery中$.post和$.ajax的用法小结
Apr 28 Javascript
vuejs使用FormData实现ajax上传图片文件
Aug 08 Javascript
vue组件jsx语法的具体使用
May 21 Javascript
解决Layui数据表格中checkbox位置不居中的方法
Aug 15 Javascript
ZK中使用JS读取客户端txt文件内容问题
Nov 07 Javascript
jQuery编写QQ简易聊天框
Aug 27 jQuery
OpenLayers3实现地图鹰眼以及地图比例尺的添加
Sep 25 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编程语言开发动态WAP页面
2006/10/09 PHP
mysq GBKl乱码
2006/11/28 PHP
PHP中的按位与和按位或操作示例
2014/01/27 PHP
PHP实现的mysql操作类【MySQL与MySQLi方式】
2017/10/07 PHP
写出更好的JavaScript之undefined篇(上)
2009/11/22 Javascript
自用js开发框架小成 学习js的朋友可以看看
2010/11/16 Javascript
统计jQuery中各字符串出现次数的工具
2012/05/03 Javascript
node.js中的buffer.length方法使用说明
2014/12/14 Javascript
AngularJS语法详解(续)
2015/01/23 Javascript
jquery UI Datepicker时间控件的使用方法(加强版)
2015/11/07 Javascript
jQuery中数据缓存$.data的用法及源码完全解析
2016/04/29 Javascript
JavaScript中用let语句声明作用域的用法讲解
2016/05/20 Javascript
原生js实现商品放大镜效果
2017/01/12 Javascript
第一次记录Bootstrap table学习笔记(1)
2017/05/18 Javascript
layui前段框架日期控件使用方法详解
2017/05/19 Javascript
vue通过滚动行为实现从列表到详情,返回列表原位置的方法
2018/08/31 Javascript
vue项目实现表单登录页保存账号和密码到cookie功能
2018/08/31 Javascript
Node.js实现简单的爬取的示例代码
2019/06/25 Javascript
如何实现小程序与小程序之间的跳转
2020/11/04 Javascript
Python中的defaultdict模块和namedtuple模块的简单入门指南
2015/04/01 Python
pymongo为mongodb数据库添加索引的方法
2015/05/11 Python
Flask框架配置与调试操作示例
2018/07/23 Python
Python3基本输入与输出操作实例分析
2020/02/14 Python
浅谈Python协程
2020/06/17 Python
pycharm不以pytest方式运行,想要切换回普通模式运行的操作
2020/09/01 Python
Python导入父文件夹中模块并读取当前文件夹内的资源
2020/11/19 Python
HTML5实现表单自动验证功能实例代码
2017/01/11 HTML / CSS
阿姆斯特丹杜莎夫人蜡像馆官方网站:Madame Tussauds Amsterdam
2019/03/12 全球购物
服装机修工岗位职责
2013/12/26 职场文书
计算机应用专业自荐信
2014/07/05 职场文书
第一节英语课开场白
2015/06/01 职场文书
婚宴领导致辞
2015/07/28 职场文书
网络研修心得体会
2016/01/08 职场文书
MySQL中使用or、in与union all在查询命令下的效率对比
2021/05/26 MySQL
Django对接elasticsearch实现全文检索的示例代码
2021/08/02 Python
《巫师》是美食游戏?CDPR10月将推出《巫师》官方食谱
2022/04/03 其他游戏