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 相关文章推荐
Javascript 刷新全集常用代码
Nov 22 Javascript
超酷的网页音乐播放器DewPlayer使用方法
Dec 18 Javascript
jQuery UI Dialog 创建友好的弹出对话框实现代码
Apr 12 Javascript
使用jQuery动态加载js脚本文件的方法
Apr 03 Javascript
JavaScript使用shift方法移除素组第一个元素实例分析
Apr 06 Javascript
在 Express 中使用模板引擎
Dec 10 Javascript
Jquery实现纵向横向菜单
Jan 24 Javascript
深入剖析javascript中的exec与match方法
May 18 Javascript
Javascript快速实现浏览器系统通知
Aug 26 Javascript
浅谈vue引用静态资源需要注意的事项
Sep 28 Javascript
jQuery内容过滤选择器与子元素过滤选择器用法实例分析
Feb 20 jQuery
Vue 事件的$event参数=事件的值案例
Jan 29 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
ThinkPHP模板之变量输出、自定义函数与判断语句用法
2014/11/01 PHP
php curl 模拟登录并获取数据实例详解
2016/12/22 PHP
php中preg_replace正则替换用法分析【一次替换多个值】
2017/01/17 PHP
php+js实现裁剪任意形状图片
2018/10/31 PHP
提高代码性能技巧谈—以创建千行表格为例
2006/07/01 Javascript
jquery 学习笔记一
2010/04/07 Javascript
Bookmarklet实现启动jQuery(模仿 云输入法)
2010/09/15 Javascript
javascript 单例/单体模式(Singleton)
2011/04/07 Javascript
基于jquery的二级联动菜单实现代码
2011/04/25 Javascript
Javascript中各种trim的实现详细解析
2013/12/10 Javascript
jquery实现邮箱自动补全功能示例分享
2014/02/17 Javascript
AngularJs自定义服务之实现签名和加密
2016/08/02 Javascript
微信小程序 设置启动页面的两种方法
2017/03/09 Javascript
从零开始学习Node.js系列教程之基于connect和express框架的多页面实现数学运算示例
2017/04/13 Javascript
关于vue-router路径计算问题
2017/05/10 Javascript
详解redis在nodejs中的应用
2018/05/02 NodeJs
Vue中的基础过渡动画及实现原理解析
2018/12/04 Javascript
分析用Python脚本关闭文件操作的机制
2015/06/28 Python
老生常谈python函数参数的区别(必看篇)
2017/05/29 Python
对python打乱数据集中X,y标签对的方法详解
2018/12/14 Python
使用PIL(Python-Imaging)反转图像的颜色方法
2019/01/24 Python
罗德与泰勒百货官网:Lord & Taylor
2016/08/12 全球购物
Richards网上商店:当代时尚,遍布巴西
2019/11/03 全球购物
J2ee常用的设计模式?说明工厂模式
2015/05/21 面试题
音乐专业应届生教师求职信
2013/11/04 职场文书
公司领导推荐信
2013/11/12 职场文书
工程负责人任命书
2014/06/06 职场文书
爱护公物演讲稿
2014/09/09 职场文书
2014年连锁店圣诞节活动方案
2014/12/09 职场文书
优秀教师申报材料
2014/12/16 职场文书
护理专业自荐信范文
2015/03/06 职场文书
辩论会主持词
2015/07/03 职场文书
2016应届毕业生实习心得体会
2015/10/09 职场文书
学校教师培训工作总结
2015/10/14 职场文书
Centos7中MySQL数据库使用mysqldump进行每日自动备份的编写
2021/08/02 MySQL
MySQL子查询中order by不生效问题的解决方法
2021/08/02 MySQL