兼容值类型的JavaScript对象Clone方法

本文介绍了一种适用于JavaScript中各种类型的对象克隆方法,包括基本数据类型和复杂对象,并通过测试验证了其正确性和兼容性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    对象的克隆是OOP中常用的一个方法,可是JavaScript的对象(各种数据类型都是)却没有提供一个Clone方法。上次我 实现了一个Clone方法,可是一直有个小毛病,就是遇到"值类型"就晕菜了。你或许会觉得值类型也Clone,搞笑吧?可是JavaScript动态类型语言,其实你在调用时可能更本不知道它是什么类型,能克隆"值类型"将会使代码具有很好的兼容性。

    当然由于我们可以使用typeof方法获取对象的基本类型,然后一个switch,该干嘛干嘛不就搞定了吗?这个... 我希望我的Clone能不去判断每种具体的类型,而尽量使用JavaScript语言提供的机制来完成,这也是上次那个Clone方法不能Clone值类型的原因。

    昨天 麻袋同学给出了一个很棒的解决值类型Clone问题的方法,使用代码:
  objClone  =   new   this .constructor( this .valueOf());
    代替我原来的:
 objClone  =   new   this .constructor();

    这样一来值类型Clone的问题迎刃而解,原理( 麻袋解释的):
  对于 date, boolean, number 这三种基本的数据类型,执行 
 var objClone 
=   new   this .constructor(); 
 的时候,得到的是默认值。而真实的值又没有属性可引用到,所以,只能在初始化的时候,以参数形式赋默认值。 
 var objClone 
=   new   this .constructor( this .valueOf()); 

    不过后来 麻袋发现它的代码处理Object的时候有问题,于是给出了:
  var  objClone; 
 
if ( this .constructor  ==  Object ) 
    objClone 
=   new   this .constructor(); 
 
else  
    objClone 
=   new   this .constructor( this .valueOf()); 

    不能克隆Object的理论依据(from Script56.chm):
    obj = new Object([value]) 
    参数
    obj 
    必选项。要赋值为 Object 对象的变量名。 
    value 
    可选项。任意一种 JScript 基本数据类型。(Number、Boolean、或 String。)如果 value 为一个对象,返回不作改动的该对象。如果 value 为 null、undefined,或者没有给出,则产生没有内容的对象。
 
    上面红字中的"对象",因该指的是: new Object()这样的实例,用代码来翻译就是:
  var  obj  =   new  Object();
  obj.asdf 
=  'asdf';
  obj2 
=   new  Object(obj);
  alert(obj
=== obj2);

    结果是啥? true!

    我在原来那个Clone的测试中,设计我的测试代码的第一个数据类型时,出了点错误,我用Literal的语法方式写的obj其实是Object的实例。本来我是想测试用户定义类型,应该这么弄:
   function  JSClass()
  {
      
this .abc  =  'abc';
      
this .faint  =  ['f', 'a', 'i', 'n', 't'];
      
this .toString  =   function ()
      {
          
return  'abc:'  +   this .abc  +  ', faint:['  +   this .faint  +  ']';
      };
  }
  
var  jsClass  =   new  JSClass();
  
var  classClone  =  jsClass.Clone();
  
var  classClone2  =  jsClass.Clone();
  classClone2.abc 
=  'def';
  
for  (  var  i = 0  ; i  <  classClone2.faint.length ;  ++ i ) classClone2.faint[i]  =  ' - '; 
  Render('JSclass', jsClass, classClone, classClone2, 
true );
 
     这个JSClass也是适合使用new this.consturctor(this.valueOf())这种方式来Clone,这时的参数不会影响它生成的对象的。

     结合 麻袋的修改,兼容版的JavaScript Clone方法出来了
  //  Authors Birdshome, 麻袋@博客园  
 
Object.prototype.Clone  =   function ()
 {
    
var  objClone;
    
if  (  this .constructor  ==  Object ) objClone  =   new   this .constructor(); 
    
else  objClone  =   new   this .constructor( this .valueOf()); 
    
for  (  var  key  in   this  )
    {
        
if  ( objClone[key]  !=   this [key] )
        { 
            
if  (  typeof ( this [key])  ==  'object' )
            { 
                objClone[key] 
=   this [key].Clone();
            }
            
else
            {
                objClone[key] 
=   this [key];
            }
        }
    }
    objClone.toString 
=   this .toString;
    objClone.valueOf 
=   this .valueOf;
    
return  objClone; 
 }    

    至于需要不要把Object的默认方法都copy一遍,我也说不清楚,就暂时copy这两个最容易被重写的吧,不然要列一大排地说。

    测试结果附图:
   JScriptClone2.gif
    测试代码:
     < script  language ="javascript" > </ script >
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值