JavaScript 赋值机制详解:基本类型传值与对象类型传址
本文深入解析 JavaScript 中的赋值行为,区分基本数据类型的值传递与对象类型的引用传递。通过代码示例说明变量赋值时的内存交互差异,并探讨如何模拟基本类型的传址行为及实现对象的深拷贝,帮助开发者理解数据共享与隔离的底层逻辑。
JavaScript 赋值机制概述
在 JavaScript 中,类型赋值的行为类似于变量之间的传递方式,理解这一机制至关重要。
对于基本数据类型,赋值操作本质上是值的传递。
具体代码示例如下:
var a=5;
var b=a;
b=3;
alert(a);//提示5
alert(b);//提示3 从上述结果可以看出,修改变量 b 的值并不会影响变量 a。这是因为基本数据类型的赋值是将具体的数值复制一份传递给新变量,两个变量在内存中独立存在,互不干扰。
对象类型的传址行为
相比之下,对象类型的赋值则是传递引用地址(传址)。
相关代码如下:
var a=new Object();
a.x=5;
var b=a;
b.x=3;
alert(a.x);//提示3
alert(b.x);//提示3 由于对象类型赋值传递的是内存地址,因此变量 b 和变量 a 指向同一个对象。对 b 的属性进行修改,实际上也改变了 a 所指向对象的属性,二者相互影响。
为了进一步澄清这一概念,再举一个例子:
代码如下:
var a=new Object();
a.x=5;
var b=a;
alert(b.x);//提示5,b.x即a.x,都是5
a.x=3;//改a.x即改b.x,都是3了
alert(a.x);//提示3
alert(b.x);//提示3 对象属性的赋值规则
需要注意的是,当对对象类型的属性进行互相赋值时,其行为不再取决于对象本身,而是取决于该属性的数据类型。
如果属性是基本数据类型,则执行传值操作;如果属性是对象类型,则执行传址操作。举例说明:
代码如下:
var a=new Object();
a.x=5; var b=new Object();
b.x=a.x; b.x=3;
alert(a.x);//提示5
alert(b.x);//提示3 在上述代码中,虽然涉及两个不同的对象,但赋值的是基本数据类型的属性 x。因此,b.x 获得的是 a.x 的值副本,两者在内存中互相独立,修改 b.x 不会影响 a.x。
代码示例如下:
var a=new Object();
a.x=5;
var b=a.x;
b=3;
alert(a.x);/提示/5
alert(b);//提示3 这同样表明,当基本数据类型的变量 b 与对象 a 的基本类型属性 x 进行赋值时,只是值的传递,两者互不影响。
然而,如果对象的属性本身也是对象类型,那么对该属性的赋值将遵循传址规则。
代码如下:
var a=new Object();
a.x=new Object;
a.x.n=5;
var b=a.x;
alert(b.n);//提示5
b.n=3;//也就改了a.x的n
alert(a.x.n);//提示3
alert(b.n);//提示3 在此例中,对象 a 的属性 x 被定义为一个 Object 对象。当将 b 赋值为 a.x 时,b 和 a.x 指向同一个内部对象,因此修改 b.n 会同步反映在 a.x.n 上,二者互通且互相影响。
————
对象深拷贝的实现
如果希望对象类型变量赋值时仅拷贝属性值,而不形成引用共享(即避免“同生共死”的引用关系),该如何处理?
可以使用以下函数来实现深拷贝:
代码如下:
var DeepCopy = function(destination, source)
{
for (var property in source)
{
var copy = source[property];
if ( destination === copy ) continue;
if ( typeof copy === "object" )
{
destination[property] = DeepCopy(destination[property] || {}, copy);
}
else
{
destination[property] = copy;
}
}
return destination;
} 使用方法如下:
代码如下:
var a=new Object;
a.x=5;
a.y=3;
var b=new Object;
DeepCopy(b,a);
alert(b.x);//提示5
alert(b.y);//提示3
b.x=8;
alert(a.x);//提示5 可以看到,修改 b.x 的值并未影响 a.x,说明 DeepCopy 函数成功实现了属性的独立拷贝。
上述 DeepCopy 函数是一个实现对象深拷贝的有效工具。
至此,我们实现了对象类型的模拟“传值”效果。
模拟基本类型的传址
那么,如何模拟基本数据类型的“传址”行为呢?
可以通过使用 Array 对象来实现。
代码如下:
function change(a)
{
a[0]=5;
alert(a);//提示5
}
var x=[3];
alert(x);//提示3
change(x);
alert(x);//提示5 将变量赋值为包含数据的数组(如 [xx]),实际上是将一个 Array 对象赋值给变量。由于数组属于对象类型,传递时遵循传址规则,因此可以通过操作数组元素来模拟基本类型的传址效果。
当然,也可以使用任意对象类型的属性来模拟这一行为。
JS语法错误会阻止加载吗?区分SyntaxError与资源加载失败
2026-11-05 16:08:46
JavaScript常见SyntaxError语法错误排查与修复方法
2026-11-05 13:58:44
JS中slice、substring和substr截取字符串的区别
2026-11-05 13:43:47
JS 转 TS 手动迁移最佳实践:从配置 tsconfig 到消除 any 类型
2026-11-05 11:53:32
为什么JS数组push后得到的是数字而不是数组?
2026-11-05 09:59:18
