锁定老帖子 主题:jQuery源码分析-extend函数
精华帖 (1) :: 良好帖 (0) :: 新手帖 (10) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-07-16
最后修改:2010-07-18
这是我的处女贴,请大家多多关照! /*! * jQuery源码分析-extend函数 * jQuery版本:1.4.2 * * ---------------------------------------------------------- * 函数介绍 * jQuery.extend与jQuery.fn.extend指向同一个函数对象 * jQuery.extend是jQuery的属性函数(静态方法) * jQuery.fn.extend是jQuery函数所构造对象的属性函数(对象方法) * * ---------------------------------------------------------- * 使用说明 * extend函数根据参数和调用者实现功能如下: * 1.对象合并: * 对象合并不区分调用者,jQuery.extend与jQuery.fn.extend完全一致 * 也就是说对jQuery对象本身及jQuery所构造的对象没有影响 * 对象合并根据参数区分,参数中必须包括两个或两个以上对象 * 如:$.extend({Object}, {Object}) 或 $.extend({Boolean},{Object}, {Object}) * 对象合并返回最终合并后的对象,支持深度拷贝 * * 2.为jQuery对象本身增加方法: * 这种方式从调用者和参数进行区分 * 形式为 $.extend({Object}) * 这种方式等同于 jQuery.{Fnction Name} * * 3.原型继承: * 原型继承方式可以为jQuery所构造的对象增加方法 * 这种方式也通过调用者和参数进行区分 * 形式为 $.fn.extend({Object}) * 这种方式实际上是将{Object}追加到jQuery.prototype,实现原型继承 * * ---------------------------------------------------------- * */ // jQuery.fn = jQuery.prototype // jQuery.fn.extend = jQuery.prototype.extend jQuery.extend = jQuery.fn.extend = function(){ //目标对象 var target = arguments[0] || {}, //循环变量,它会在循环时指向需要复制的第一个对象的位置,默认为1 //如果需要进行深度复制,则它指向的位置为2 i = 1, //实参长度 length = arguments.length, //是否进行深度拷贝 //深度拷贝情况下,会对对象更深层次的属性对象进行合并和覆盖 deep = false, //用于在复制时记录参数对象 options, //用于在复制时记录对象属性名 name, //用于在复制时记录目标对象的属性值 src, //用于在复制时记录参数对象的属性值 copy; //只有当第一个实参为true时,即需要进行深度拷贝时,执行以下分支 if (typeof target === "boolean") { //deep = true,进行深度拷贝 deep = target; //进行深度拷贝时目标对象为第二个实参,如果没有则默认为空对象 target = arguments[1] || {}; //因为有了deep深度复制参数,因此i指向的位置为第二个参数 i = 2; } //当目标对象不是一个Object且不是一个Function时(函数也是对象,因此使用jQuery.isFunction进行检查) if (typeof target !== "object" && !jQuery.isFunction(target)) { //设置目标为空对象 target = {}; } //如果当前参数中只包含一个{Object} //如 $.extend({Object}) 或 $.extend({Boolean}, {Object}) //则将该对象中的属性拷贝到当前jQuery对象或实例中 //此情况下deep深度复制仍然有效 if (length === i) { //target = this;这句代码是整个extend函数的核心 //在这里目标对象被更改,这里的this指向调用者 //在 $.extend()方式中表示jQuery对象本身 //在 $.fn.extend()方式中表示jQuery函数所构造的对象(即jQuery类的实例) target = this; //自减1,便于在后面的拷贝循环中,可以指向需要复制的对象 --i; } //循环实参,循环从第1个参数开始,如果是深度复制,则从第2个参数开始 for (; i < length; i++) { //当前参数不为null,undefined,0,false,空字符串时 //options表示当前参数对象 if ((options = arguments[i]) != null) { //遍历当前参数对象的属性,属性名记录到name for (name in options) { //src用于记录目标对象中的当前属性值 src = target[name]; //copy用于记录参数对象中的当前属性值 copy = options[name]; //存在目标对象本身的引用,构成死循环,结束此次遍历 if (target === copy) { continue; } //如果需要进行深度拷贝,且copy类型为对象或数组 if (deep && copy && (jQuery.isPlainObject(copy) || jQuery.isArray(copy))) { //如果src类型为对象或数组,则clone记录src //否则colne记录与copy类型一致的空值(空数组或空对象) var clone = src && (jQuery.isPlainObject(src) || jQuery.isArray(src)) ? src : jQuery.isArray(copy) ? [] : {}; //对copy迭代深度复制 target[name] = jQuery.extend(deep, clone, copy); //如果不需要进行深度拷贝 } else if (copy !== undefined) { //直接将copy复制给目标对象 target[name] = copy; } } } } //返回处理后的目标对象 return target; }; /** * jQuery框架本身对extend函数的使用非常频繁 * 典型示例为jQuery.ajax * */ //使用extend对jQuery对象本身进行扩展,只给了一个参数对象 //该对象中的属性将被追加到jQuery对象中 jQuery.extend({ //jQuery.ajax //$.ajax //这里的origSettings参数是自定义的ajax配置 //jQuery对象本身有一个ajaxSettings属性,是默认的ajax配置 ajax: function(origSettings){ //这里使用extend对ajax配置项进行合并 //第一个参数表示进行深度拷贝 //首先将第3个参数jQuery.ajaxSettings(即jQuery默认ajax配置)复制到第2个参数(一个空对象) //然后将第4个参数(自定义配置)复制到配置对象(覆盖默认配置) //这里的s就得到了最终的ajax配置项 var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings); //其它相关代码...(省略) } }); 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-07-19
现在的人都很喜欢简单的,最好一句话就把Extend的原理说清楚了。
我觉得Javascript所谓的extends就是把父类的属性,复制到子类。 |
|
返回顶楼 | |
发表时间:2010-07-20
楼上的,读源码是最有效的学习方式,难得楼主写出这么详细的注释。你一句话说出来,除了能把它用好,还能学到什么?
简单这个概念是面对用户的,做程序员的在学习上可不能对自己要求“简单”。只知其表而不知其里的人,永远只能做coder,永远只能跟在技术的屁股后面;只有深入了解了你用的技术,才能算是programmer。 鼓励楼主写出更多的源码分析,加油! |
|
返回顶楼 | |
发表时间:2010-07-20
楼主辛苦了,学习榜样,支持你!
|
|
返回顶楼 | |
发表时间:2010-07-20
恩,不错,jQuery一直在用,可没时间看源码,改天倡议下每人贡献个函数分析,免得各自分析时费时费力
|
|
返回顶楼 | |
发表时间:2010-07-20
感谢大家鼓励!我会将jQuery源码全部分析注释一遍,和大家一起学习讨论。
|
|
返回顶楼 | |
发表时间:2010-07-21
lz v5
|
|
返回顶楼 | |
发表时间:2010-07-21
看来有点深度,哥们,能不能结合一些例子!这似乎更易理解些吧!
|
|
返回顶楼 | |
发表时间:2010-07-21
Quen 写道 看来有点深度,哥们,能不能结合一些例子!这似乎更易理解些吧! 我想没有比源码更好的例子了,如果这也不容易理解的话,看来是我注释的还不够清楚。。。 |
|
返回顶楼 | |
发表时间:2010-07-22
helloworld1987 写道 Quen 写道 看来有点深度,哥们,能不能结合一些例子!这似乎更易理解些吧!
我想没有比源码更好的例子了,如果这也不容易理解的话,看来是我注释的还不够清楚。。。 首先赞LZ的精神。另:我想ls是希望先从extend函数的使用开始说起,然后结合例子来深入解析源代码,若能总结出源代码中的技巧和好处的话,相信会印象更加深刻。 |
|
返回顶楼 | |