首页 > 代码库 > 用浅/深拷贝、和HTML5方法解决js对象的引用的问题

用浅/深拷贝、和HTML5方法解决js对象的引用的问题

先来看一个例子

例一:

var a=[1,2,3];var b=a;b.push(4);alert(b);//1,2,3,4alert(a);//1,2,3,4
var a=[1,2,3];var b=a;b=[1,2,3,4]alert(b);//1,2,3,4alert(a);//1,2,3

这两种方法得出的结果是不一样的。

第一个程序,是对象的引用, 把a的值附给b,a与b之间是引用的关系,当两者之间是引用的关系时,改变任一变量,都会影响另一个变量。

第二个程序,只是对b的值改变,虽然b=a ,但是当改变b的值时,又重新建立了一个地址,这个地址与a无关,所以在改变b值时,与a无关,这有点类似于C中的指针

再来看一个例子

例二:

var a={     name:‘hello‘          };var b=a;b.name=‘hi‘;alert(a.name);//当然了,这个结果肯定是hi

如何解决上面的问题呢?

var a={     name:‘hello‘          };function copy(){    var b={};    for(var attr in a){        b[attr]=a[attr]    }       return b  }b.name=‘hi‘;alert(a.name); //这时的结果就是hello了        

上面的方法叫浅拷贝,利用for in 把a中属性拷贝给b,但是只是拷贝了一个副本,实际上当修改b的值是不会改变a的值的。当然有浅拷贝就有深拷贝。

var a={     name:‘{value:‘world‘}‘          }function copy(){    var b={};    for(var attr in a){        b[attr]=a[attr];    }       return b  }b.name.value=‘space‘;alert(a.name.value); //这时的结果是space

这时候大家或许或纳闷,用了拷贝了怎么结果还是space呢!因为JSON里面又有一个 value:‘world‘ 这个类型是一个对象,你拷贝过来还是对象,还是对象的引用,所以结果就是space,当然了,或许有会说那就再用一次copy就行。由结果再调用一次copy,对了,就是递归的含义,在函数内部调用函数本身。稍微修改一下程序即可

var a={     name:‘{value:‘world‘}‘          }function deepCopy(){     if(typeof a!=‘object‘){        return a    }       var b={};    for(var attr in a){        b[attr]=deepCopy(a[attr]);    }       return b  }b.name.value=‘space‘;alert(a.name.value); //这时的结果就是world

改的地方有两处,1、执行函数内部调用函数本身   b[attr]=deepCopy(a[attr])   2、终止条件typeof a!=‘object‘  就像上面说的,你用浅拷贝拷的是对象,终止条件就是检测类型不是对象的时候,返回a的值。这样就解决了问题。 上面的方法就是深拷贝

例三:

现在了解了浅/深拷贝,想用HTML5方法去解决。在解决之前,我们很有必要去了解HTML5之前如何将字符串转换成js语句,如下:

var str=‘function task(){alert(‘hello‘)}‘var fn=eval(str);task(); //hello

HTML5如何把JSON格式的字符串转成JSON对象,用JSON.parse() 如下:

var a=‘{  ‘name‘:‘hello‘;  };‘var json=JSON.parse(a);alert(json.name); //hello

这个name上加了 ‘ ‘  不加‘ ‘ 时不严格的JSON,JSON.parse 方法要求必须是严格的JSON

如何将JSON对象转成JSON格式的字符串呢,用JSON.stringify()  如下:

var a={   name:‘hello‘  };var json=JSON.stingify(a);alert(json); // ‘{‘name‘:‘hello‘}‘
这时的结果就是 ‘{‘name‘:‘hello‘}‘,这时候就明白了为什么要用严格的JSON格式了

那么用HTML5怎么解决问题呢,那就先把JSON转成字符串,再把JSON格式的字符换转成对象,实习上引用的还是a的副本,并没有真正引用a。这就和拷贝中的
副本原理是一样的。如下:
var a={    name:‘hello‘  };var str=JSON.stringify(a);var obj=JSON.parse(str);var b=obj;b.name=‘hi‘;alert(a.name);//hello
拓展:

   这种方法实际上在8以下是不兼容的,如何兼容呢,就是引用一个json文件:json2.js,如下

<script type=‘text/javascript‘ src=http://www.mamicode.com/‘json2.js‘></script>

 

 

 

 

用浅/深拷贝、和HTML5方法解决js对象的引用的问题