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 单击li防止重复加载的实现代码
Dec 24 Javascript
jQuery动态地获取系统时间实现代码
May 24 Javascript
基于jquery扩展漂亮的CheckBox(自己编写)
Nov 19 Javascript
JS不能跨域借助jquery获取IP地址的方法
Aug 20 Javascript
javascript基本类型详解
Nov 28 Javascript
jQuery插件MixItUp实现动画过滤和排序
Apr 12 Javascript
javaScript如何跳出多重循环break、continue
Sep 01 Javascript
JavaScript实现单例模式实例分享
Dec 22 Javascript
微信小程序提交form操作示例
Dec 30 Javascript
JS数组方法slice()用法实例分析
Jan 18 Javascript
node.js基础知识汇总
Aug 25 Javascript
用JS写一个发布订阅模式
Nov 07 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的hash算法介绍
2014/02/13 PHP
PHP面向对象教程之自定义类
2014/06/10 PHP
Yii框架数据库查询、增加、删除操作示例
2019/10/14 PHP
JavaScript 基础知识 被自己遗忘的
2009/10/15 Javascript
jquery 面包屑导航 具体实现
2013/06/05 Javascript
用js将内容复制到剪贴板兼容浏览器
2014/03/18 Javascript
实例讲解JS中数组Array的操作方法
2014/05/09 Javascript
javascript的数组和常用函数详解
2014/05/09 Javascript
JavaScript实现找出数组中最长的连续数字序列
2014/09/03 Javascript
深入理解JavaScript系列(50):Function模式(下篇)
2015/03/04 Javascript
使用堆实现Top K算法(JS实现)
2015/12/25 Javascript
jQuery form插件的使用之处理server返回的JSON, XML,HTML数据
2016/01/26 Javascript
jQuery遍历json的方法分析
2016/04/16 Javascript
使用开源工具制作网页验证码的方法
2016/10/17 Javascript
jQuery复合事件结合toggle()方法的用法示例
2017/06/10 jQuery
JavaScript实现离开页面前提示功能【附jQuery实现方法】
2017/09/26 jQuery
JavaScript常用内置对象用法分析
2019/07/09 Javascript
JavaScript创建、读取和删除cookie
2019/09/03 Javascript
使用webpack将ES6转化ES5的实现方法
2019/10/13 Javascript
Vue学习之组件用法实例详解
2020/01/06 Javascript
原生JS实现弹幕效果的简单操作指南
2020/11/10 Javascript
Python序列化基础知识(json/pickle)
2017/10/19 Python
python3.5基于TCP实现文件传输
2020/03/20 Python
Python如何发送与接收大型数组
2020/08/07 Python
Python Selenium破解滑块验证码最新版(GEETEST95%以上通过率)
2021/01/29 Python
CSS3的first-child选择器实战攻略
2016/04/28 HTML / CSS
HTML5 window/iframe跨域传递消息 API介绍
2013/08/26 HTML / CSS
美国家喻户晓的保健品品牌:Vitamin World(维他命世界)
2016/08/19 全球购物
迟到检讨书500字
2014/02/05 职场文书
数学教学随笔感言
2014/02/17 职场文书
2014年党务公开方案
2014/05/08 职场文书
法定代表人授权委托书范文
2014/08/02 职场文书
2014乡镇干部对照检查材料思想汇报
2014/09/26 职场文书
父亲节寄语大全
2015/02/27 职场文书
4种非常实用的python内置数据结构
2021/04/28 Python
Django框架中视图的用法
2022/06/10 Python