当前位置:编程学习 > JAVA >>

jQuery.extend()的实现方式

jQuery中的extend()

  extend()函数是jQuery的基础函数之一,作用是扩展现有的对象。例如下面的代码:
Html代码   
• <script type="text/javascript" src="jquery-1.5.2.js"></script>  
• <script>  
• obj1 = { a : 'a', b : 'b' };  
• obj2 = {  x : { xxx : 'xxx', yyy : 'yyy' },  y : 'y' };  
•   
• $.extend(true, obj1, obj2);  
•   
• alert(obj1.x.xxx);  // 得到"xxx"  
•   
• obj2.x.xxx = 'zzz';  
• alert(obj2.x.xxx);  // 得到"zzz"  
• alert(obj1.x.xxx);  // 得带"xxx"  
• </script>  

  $.extend(true, obj1, obj2)表示以obj2中的属性扩展对象obj1,第一个参数设为true表示深复制。
  虽然obj1中原来没有"x"属性,但经过扩展后,obj1不但具有了"x"属性,而且对obj2中的"x"属性的修改也不会影响到obj1中"x"属性的值,这就是所谓的“深复制”了。
浅复制的实现

  如果仅仅需要实现浅复制,可以采用类似下面的写法:
Javascript代码   
• $ = {  
•      extend : function(target, options) {  
•         for (name in options) {  
•             target[name] = options[name];  
•         }  
•         return target;  
•     }  
• };  

  也就是简单地将options中的属性复制到target中。我们仍然可以用类似的代码进行测试,但得到的结果有所不同(假设我们的js命名为“jquery-extend.js”):
Html代码   
• <script type="text/javascript" src="jquery-extend.js"></script>  
• <script>  
• obj1 = { a : 'a', b : 'b' };  
• obj2 = {  x : { xxx : 'xxx', yyy : 'yyy' },  y : 'y' };  
•   
• $.extend(obj1, obj2);  
•   
• alert(obj1.x.xxx);  // 得到"xxx"  
•   
• obj2.x.xxx = 'zzz';  
• alert(obj2.x.xxx);  // 得到"zzz"  
• alert(obj1.x.xxx);  // 得带"zzz"  
• </script>  

  obj1中具有了"x"属性,但这个属性是一个对象,对obj2中的"x"的修改也会影响到obj1,这可能会带来难以发现的错误。
深复制的实现

  如果我们希望实现“深复制”,当所复制的对象是数组或者对象时,就应该递归调用extend。如下代码是“深复制”的简单实现:
Javascript代码   
• $ = {  
•     extend : function(deep, target, options) {  
•         for (name in options) {  
•             copy = options[name];  
•             if (deep && copy instanceof Array) {  
•                 target[name] = $.extend(deep, [], copy);  
•             } else if (deep && copy instanceof Object) {  
•                 target[name] = $.extend(deep, {}, copy);  
•             } else {  
•                 target[name] = options[name];  
•             }  
•         }  
•         return target;  
•     }  
• };  

  具体分为三种情况:
  1. 属性是数组时,则将target[name]初始化为空数组,然后递归调用extend;
  2. 属性是对象时,则将target[name]初始化为空对象,然后递归调用extend;
  3. 否则,直接复制属性。

  测试代码如下:
Html代码   
• <script type="text/javascript" src="jquery-extend.js"></script>  
• <script>  
• obj1 = { a : 'a', b : 'b' };  
• obj2 = {  x : { xxx : 'xxx', yyy : 'yyy' },  y : 'y' };  
• $.extend(true, obj1, obj2);  
• alert(obj1.x.xxx);  // 得到"xxx"  
• obj2.x.xxx = 'zzz';  
• alert(obj2.x.xxx); // 得到"zzz"  
• alert(obj1.x.xxx); // 得到"xxx"  
• </script>  

  现在如果指定为深复制的话,对obj2的修改将不会对obj1产生影响了;不过这个代码还存在一些问题,比如“instanceof Array”在IE5中可能存在不兼容的情况。jQuery中的实现实际上会更复杂一些。
更完整的实现 www.zzzyk.com

  下面的实现与jQuery中的extend()会更接近一些:
Javascript代码   
• $ = function() {  
•     var copyIsArray,  
•         toString = Object.prototype.toString,  
•         hasOwn = Object.prototype.hasOwnProperty;  
•   
•     class2type = {  
•         '[object Boolean]' : 'boolean',  
•         '[object Number]' : 'number',  
•         '[object String]' : 'string',  
•         '[object Function]' : 'function',  
•         '[object Array]' : 'array',  
•         '[object Date]' : 'date',  
•         '[object RegExp]' : 'regExp',  
•         '[object Object]' : 'object'  
•     },  
•   
•     type = function(obj) {  
•         return obj == null ? String(obj) : class2type[toString.call(obj)]

补充:web前端 , JavaScript ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,