jquery源码分析之插件扩展的实现
今天有网友留言问jquery插件参数扩展方法extend的使用问题,分析一段jquery插件扩展实现的源代码,解释一下插件开发的困惑。
问题的原话如下:var opts = $.extend({}, $.fn.hilight.defaults, options); extend的第一个参数[b]{}[/b]有什么用处呢?老实说,我也不能确定,为了不误人子弟,还是老老实实把jquery源码翻出来看了一下,豁然开朗。不多说,且先看代码:
- jQuery.extend = jQuery.fn.extend = function() {
- // target的初始值为第一个参数值与{}或操作的结果,deep变量表示是否实行深度拷贝
- var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
- // 如果是(对象的)深度拷贝(第一个参数值应指定为true),则进行深度拷贝
- if ( target.constructor == Boolean ) {
- deep = target;
- target = arguments[1] || {};//这里target被重新赋值了,即$.fn.hilight.defaults的值,当然,这里没有指定为深拷贝
- i = 2;// 跳过后面的for循环
- }
- // 如果target初始值类型不对,置为{}
- if ( typeof target != "object" && typeof target != "function" )
- target = {};
- // 如果只有一个参数被传入,则将参数表示的对象的属性和方法复制给jQuery或jQuery对象,即扩展的是jquery对象自身(注意:jquery源码中大量内置方法和属性都是通过这种方式实现的)
- if ( length == 1 ) {
- target = this;
- i = 0;
- }
- for ( ; i < length; i++ )
- // 仅仅处理非空,非undefined类型的值
- if ( (options = arguments[ i ]) != null )
- // 扩展基本的对象
- for ( var name in options ) {
- // 避免options中指定值错误或者冲突引起的死循环
- if ( target === options[ name ] )
- continue;
- // 递归处理,实现默认对象到自定义对象的深度拷贝
- if ( deep && options[ name ] && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType )
- target[ name ] = jQuery.extend( target[ name ], options[ name ] );
- // 避免出现undefined类型的数据进入插件内部
- else if ( options[ name ] != undefined )
- target[ name ] = options[ name ];
- }
- // 返回修改后的对象
- return target;
- };
通过代码分析,我们对于为插件指定属性以及插件的实现应该是很清楚了(注意开头的jQuery.extend = jQuery.fn.extend,表示两者是一致的实现方式),因此对于插件扩展中的属性,可以有
1.extend(src) 将src对象的属性和方法逐一复制给jQuery或jQuery对象
2.extend(dest,src1,src2,src3…srcN) 将src1、src2…对象的属性和方法逐一复制给dest对象,需要注意的是,在复制的过程中,排在后面的参数(对象)将会覆盖排在前面的参数的属性和方法;实际上,该方法和后面的方法3都提供了一种“深度继承”的方法,即:参数一表示的对象可以通过该方法一次实现逐一按层次的父类继承。
3.extend(true,dest,src1,src2,src3…srcN) 深度拷贝对象
4.extend({},dest,src1,src2,src3…srcN) 加上返回对象的默认值
一般说来,作插件属性的扩展用 $.extend({}, $.fn.hilight.defaults, options)或者 $.extend($.fn.hilight.defaults, options)即可,这里hilight表示插件名。defaults表示提供的默认值,options表示设置的新的值对象集合,{}可有可无,可以默认加上,表示返回值的初始值,如果没有指定,在扩展的实现里还会自己加上。是不是感觉豁然开朗了呢,希望对各位有所帮助。









11月 17th, 2008 at 15:00
不错的blog,还是很有帮助啊