用浅/深拷贝、和HTML5方法解决js对象的引用的问题
先来看一个例子
例一:
var a=[1,2,3];
var b=a;
b.push(4);
alert(b);//1,2,3,4
alert(a);//1,2,3,4
var a=[1,2,3];
var b=a;
b=[1,2,3,4]
alert(b);//1,2,3,4
alert(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(a){
var b={};
for(var attr in a){
b[attr]=a[attr]
}
return b
}
copy(a).name='hi';
alert(a.name); //这时的结果就是hello了
上面的方法叫浅拷贝,利用for in 把a中属性拷贝给b,但是只是拷贝了一个副本,实际上当修改b的值是不会改变a的值的。当然有浅拷贝就有深拷贝。
var a={
name:{value:'world'}
}
function copy(a){
var b={};
for(var attr in a){
b[attr]=a[attr];
}
return b
}
copy(a).name.value='space';
alert(a.name.value); //这时的结果是space
这时候大家或许或纳闷,用了拷贝了怎么结果还是space呢!因为JSON里面又有一个 value:'world' 这个类型是一个对象,你拷贝过来还是对象,还是对象的引用,所以结果就是space,当然了,或许有会说那就再用一次copy就行。由结果再调用一次copy,对了,就是递归的含义,在函数内部调用函数本身。稍微修改一下程序即可
var a={
name:{value:'world'}
}
function deepCopy(a){
if(typeof a!='object'){
return a
}
var b={};
for(var attr in a){
b[attr]=deepCopy(a[attr]);
}
return b
}
deepCopy(a).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='json2.js'></script>
用浅/深拷贝、和HTML5方法解决js对象的引用的问题的更多相关文章
- json转js对象方法,JS对象转JSON方法
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- JS对象的引用,对象的拷贝
目录 一.场景 二.浅拷贝 三.深拷贝 一.场景 除了基本类型跟null,对象之间的赋值,只是将地址指向同一个,而不是真正意义上的拷贝 将一个对象赋值给另外一个对象. var a = [1,2,3]; ...
- 递归 与 js 对象的引用
<script> //递归 function test(n) { if (n == 1) { return 1 } console.log(n) return n * test(n - 1 ...
- 让javascript加载速度倍增的方法(解决JS加载速度慢的问题)
通常我们的网站里面会加载一些js代码,统计啊,google广告啊,百度同盟啊,阿里妈妈广告代码啊,一堆,最后弄得页面加载速度很慢,很慢. 解决办法:换一个js包含的方式,让javascript加载速度 ...
- MVC扩展Url.Action方法解决复杂对象参数问题
1:问题描述 @Url.Action("Index", "Home", new { Key = "Key", Val = new { Nam ...
- js对象的引用
/*var a = [1,2,3]; var b = [1,2,3]; alert( a == b ); //false*/ //基本类型:赋值的时候只是值得复制 /* var a = 5; var ...
- javascript基础-js对象
一.js对象的创建 1.普通最简单的方式 var teacher = new Object( ); teacher.name = "zhangsan"; teacher.age = ...
- js对象,原型,call,apply浅析
//对象直接量,创建对象最简单的方式是在js里使用对象直接量 var book = { "main title": "js", //属性里有空格,要用引号 &q ...
- 9、Cocos2dx 3.0游戏开发三查找值小工厂方法模式和对象
重开发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27704153 工厂方法模式 工厂方法是程序设计中一个 ...
随机推荐
- [译]Java设计模式之解释器
(文章翻译自Java Design Pattern: Interpreter) 解释器模式适用于当一些内容需要翻译的时候.下面的例子是一个非常简单的解释器实现.它将字母"a"和&q ...
- 等差数列6《MAC》
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXhzdGFycw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...
- js预解析问题总结
//示例 1 alert(a) // undefind. alert(fn) // function 整个函数块. var a = 1; function fn(){ return falss; }; ...
- solr的配置文件及其含义
solr与.net系列课程(二)solr的配置文件及其含义 solr与.net系列课程(二)solr的配置文件及其含义 本节内容还是不会涉及到.net与数据库的内容,但是不要着急,这都是学时s ...
- 在Win7中安装程序集到GAC
原文:在Win7中安装程序集到GAC 微软为提高系统安全,自Vista推出后,在Windows系统中加入了一个新的东东——UAC(User Account Control),这样一个新的技术使得许多操 ...
- zepto.js的基本介绍与使用
最近看到了一篇文章,是介绍一种新的js框架,名为zepto.js,他适用于移动设备已经桌面浏览器除了ie系列的.. 他兼容jquery的API,所以学起来或用起来并不吃力.他比jquery的优势在于1 ...
- Javascript多线程引擎(七)
Javascript多线程引擎(七)--synchronized关键字 经过两天的努力, 今天synchronzied关键字终于支持了, 如下是测试代码 thread() 是一个开启新线程的API, ...
- Windows Live Writer 完成开源并推出开源分支
原文:Announcing Open Live Writer - An Open Source Fork of Windows Live Writer Windows Live Writer是一款发布 ...
- facebook .net sdk 应用
浅谈 facebook .net sdk 应用 今天看了一篇非常好的文章,就放在这里与大家分享一下,顺便也给自己留一份.这段时间一直在学习MVC,另外如果大家有什么好的建议或者学习的地方,也请告知 ...
- 用py2exe打包pyqt4出现的问题(转)
使用pyqt完成窗体界面很方便,但是打包成exe之后会有问题,在网上找到解决办法如下: Another Solution to the same problem: from distutils.cor ...