本文深入解析JavaScript中对象引用与赋值的机制。通过对比基本类型与引用类型的赋值差异,说明直接赋值会导致对象共享引用。文章提供了使用JSON序列化进行浅层独立复制的方法,并指出该方法在处理嵌套对象时的局限性。此外,还探讨了将对象作为函数参数传递时的引用行为,以及将引用置空对原对象的影响,帮助开发者避免常见的引用错误。
JavaScript对象引用与赋值机制详解
本文详细解析JavaScript中对象引用与赋值的核心概念,旨在帮助读者深入理解其工作原理。
<script type="text/javascript">
//例子一: 引用
var myArrayRef = new Array(0,1,2); //创建数组对象
var mySeconArrayRef = myArrayRef; // 对象复制.
myArrayRef[0] = 100; // 修改元素值
alert(mySeconArrayRef[0]);
/**
* 输出 100; 学过其它语言的都应该知道这里应该输出的是0 为什么输出的是100呢?
* 上面程序通过把myArrayRef对象复制给了mySeconArrayRef这时就存在了2个独立的 但最初值是相同的对象
* 因为是独立的为什么修改myArrayRef会对别一个对象有影响呢?大家都知道只有当他们引用的是同一个对象时这时修改一个才会
* 对别一个产生影响.但是在javascript语言中创建的对象myArrayRef值中其时保存的是对象的引用(也就是一个地址).
* 也就是 我用 new Array生成的保存在内存中而new Array把它所在的地方告诉了myArrayRef,myArrayRef又把这地址告诉了mySeconArrayRef
* 他们两个都指向的是new Array生成对象的地址而不是把对象保存在myArrayRef中,所以通过其中的一个去修改值时其时是修改他们同指象的那对象.
*/
alert(mySeconArrayRef[0] );
//例子二: 赋值
var myVa = 'ABC'; //把ABC的值 赋予了myVa
var myVb = myVa; // myVa 赋值给 myVb
myVa = 'DEF'; //修改myVa
/**
* 输出的是:ABC. 因为是把值保存在了变量了 而不是保存的是引用地址,所以他们两个是相对独立的整体.
*/
alert(myVb);
</script>
若需创建完全独立、互不干扰的对象副本,不能仅依靠简单的赋值操作。正确做法是通过序列化转换赋值,或遍历对象的键值对来手动复制其中的方法与属性。
需注意,对象中的子对象同样遵循引用机制。因此,在遍历赋值时,必须判断子元素是否为对象类型;若是,则需递归地对子元素继续执行遍历赋值操作,以确保深层数据的独立性。
以下是通过转换赋值实现对象独立复制的具体方式:
通过转换赋值实现对象独立复制
var data = {a:1,b:2,c:3,d:[0,1,2,3]};
var str = JSON.stringify(data);
var data1 = $.parseJSON(str); //$为jQuery对象需要引入jQuery包
data1["e"] = 4;
data1["d"][0] = 11;
console.log(data);
console.log(data1);
运行上述代码后的输出结果如下:
{a: 1, b: 2, c: 3, d: [0,1,2,3]}
{a: 1, b: 2, c: 3, d: [11,1,2,3], e: 4}
可以看到,修改后的两个对象相互之间没有产生任何影响,实现了真正的独立。
当对象引用作为函数参数传递时,函数内部对对象的修改依然会影响原对象,这一点务必注意。具体示例如下:
对象作为函数参数传递的影响
var data = {a:1,b:2,c:3,d:{q:4,w:5,e:6}};
var data1 = data;
function con(data2){
data2["r"] = 5;
console.log(JSON.stringify(data2));
}
con(data1);
console.log(JSON.stringify(data));
函数执行后的输出结果如下:
{"a":1,"b":2,"c":3,"d":{"q":4,"w":5,"e":6},"r":5}
{"a":1,"b":2,"c":3,"d":{"q":4,"w":5,"e":6},"r":5}
如果在对象引用赋值后,将原引用变量置为空对象,则两者之间将不再受彼此影响。具体操作如下:
对象引用置空后的行为分析
var arr = {"a":"1","b":"2"};
var arr1 = arr;
arr = {};
arr["a"] = 2;
console.log(arr1);
console.log(arr);
置空操作后的输出结果如下:
{"a":"1","b":"2"},{"a":2}
如果您对JavaScript的其他方面感兴趣,推荐查阅本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》。
希望本文关于对象引用与赋值的阐述能对您的JavaScript程序设计工作提供有益的帮助。