对象的引用在js里面实在的太常见了。若是不注意这个问题,则每每会犯一些小白同样的错误。好比:html
var pa = { name: 'huasheng', age: '20', address: { province: 'zzz', city: 'aaa' } }; function test(param){ var addr = param.address; addr.city = "bbb"; } test(obj); console.log(obj.address.city); // bbb
// 这里函数test里面的 addr = param.address 其实就产生了一个引用
// 原本觉得的是把param的address从新赋给一个变量 addr,而后修改 addr 里面的值,不去影响param
// 可是实验结果发现,addr 和 param.address 两个实际上是一个东西。
关于Js变量引用的问题,其实就是数据类型的问题。在Js里面,有两种数据类型:基础类型和引用类型app
其中,Number, Boolean, String都是基础类型,引用类型包括:Object, Array, Function函数
你们也能够参考一下这篇文章:http://www.cnblogs.com/diva/post
既然发现了问题,那固然要来解决问题。(下面主要针对的是Object和Array两种引用类型,在实际应用中,引用里面须要变化Function的需求很少,最多要求调用一下。)url
其实,解决办法说白了,就是从新拷贝一份新的数据,若是是基础类型的,直接赋值就OK, 引用类型的须要拷贝一份出来。这里的拷贝都要求可以深层拷贝对象。spa
function deepCopy(result, source) { for (var key in source) { var copy = source[key]; if (source === copy) continue;//如window.window === window,会陷入死循环,须要处理一下 if (is(copy, "Object")) { result[key] = arguments.callee(result[key] || {}, copy); } else if (is(copy, "Array")) { result[key] = arguments.callee(result[key] || [], copy); } else { result[key] = copy; } } return result; function is(obj, type) { var toString = Object.prototype.toString; return (type === "Null" && obj === null) || (type === "Undefined" && obj === undefined ) || toString.call(obj).slice(8, -1) === type; } }
callee 的用法能够参见:JS 中的call,apply,bind 和 caller, callee
先把对象转成JSON格式的字符串,再将该字符串解析成新的对象。该方法能够一次性解决深层拷贝问题。简单易行。prototype
var pa = { name: 'huasheng', age: '20', address: { province: 'zzz', city: 'aaa' } }; var b = JSON.parse(JSON.stringify(pa)); console.log(b); b.address.city = 'bbb'; console.log(b.address.city); // bbb console.log(pa.address.city); // aaa