JavaScript 赋值机制与参数传递详解

山间有风
山间有风
发布时间:2026-10-14| 6人浏览过
原创

在 JavaScript 开发中,变量赋值和函数传参的行为往往容易混淆。核心在于区分原始值(Primitive Values)和引用值(Reference Values)。原始值直接存储在栈内存中,复制时生成独立副本;而引用值指向堆内存中的对象,赋值时传递的是内存地址的引用。理解这一机制是掌握 JS 底层逻辑的关键。

原始值与引用值的基础概念

要理解赋值机制,首先需明确两种基本数据类型的区别:

  • 原始值(Primitive Values):包括 Undefined、Null、Boolean、Number 和 String。它们在内存中以固定的大小存在于栈(Stack)中,按值访问。
  • 引用值(Reference Values):通常指 Object 及其子类型(包括数组、函数等)。它们的大小不固定,实际对象数据存储在堆(Heap)中,变量在栈中仅保存指向堆内存的地址。

注意以下代码中的细微差别:

var a = 'test';       // 原始值字符串
var b = new String('test'); // 引用值对象
var A = 'true';       // 原始值布尔/字符串(取决于上下文,此处为字符串字面量即原始值逻辑下的对比)
var B = new Boolean('true'); // 引用值对象

变量 a 和 A 存储的是具体的值,而 b 和 B 存储的是指向堆内存中对象的指针。

赋值机制:拷贝与引用

当我们将一个变量赋值给另一个变量时,JavaScript 会根据数据类型采取不同的策略。

第1步:原始值的赋值(按值拷贝)

对于原始值,赋值操作会在栈内存中创建一个新的独立区域,将原变量的值复制一份放入新区域。此后两个变量互不干扰。

var a = 1;      // 栈中存放值 1
var b = a;      // 复制一份值 1 给 b,b 也指向新的栈空间
b = 2;          // 修改 b 的值
alert(a);       // 输出 1,a 不受影响

第2步:引用值的赋值(按址引用)

对于引用值,赋值操作仅在栈内存中复制那份“地址指针”,而非堆中的实际对象。因此,多个变量可能指向堆中的同一个对象。

var A = new Object(); // 在堆中创建对象,栈中存地址
A.x = 1;
var B = A;            // B 获得与 A 相同的地址指针,两者指向同一堆对象
B.x = 2;              // 通过 B 修改对象属性
alert(A.x);           // 输出 2,因为 A 和 B 监控的是同一个对象

函数参数传递机制

函数调用时的参数传递同样遵循上述规则。无论参数是原始值还是引用值,JavaScript 始终是按值传递的,只是这个“值”对于原始值是数据本身,对于引用值则是内存地址。

第1步:传递原始值参数

当原始值作为参数传入函数时,形参接收的是实参值的副本。在函数内部修改形参,不会影响外部的实参变量。

var a = 1;
function test(m) {
    m = 2;      // 修改的是局部副本 m,不影响外部变量 a
}
test(a);
alert(a);       // 输出 1

第2步:传递引用值参数

当引用值作为参数传入函数时,形参接收到的是实参指向对象的地址。虽然形参变量本身在栈中的地址副本不能被修改以指向其他对象(一旦重新赋值则断开联系),但可以通过该地址修改堆内存中对象的属性,从而影响外部变量。

var A = new Object();
A.x = 1;
function test(M) {
    M.x = 2;    // 通过地址修改堆内存中的属性
}
test(A);
alert(A.x);     // 输出 2,外部对象被修改

综合案例分析

结合开篇的实际代码,我们可以清晰判断变量在函数执行后的状态:

var a = 'test';         // 原始值
var b = function() {};  // 引用值(函数也是对象)
b.a = 'test';           // 给函数对象添加属性

function change(m, n) {
    m = 'change';       // 1. m 是原始值拷贝,修改 m 不影响 a
    n.a = 'change';     // 2. n 是 b 的地址拷贝,修改 n.a 直接影响 b 的对象属性
}

change(a, b);

分析结果

  1. 变量 a:作为原始值(字符串)传入函数,形参 m 获得了值的拷贝。m = 'change' 仅改变了局部变量 m,函数结束后,外部变量 a 仍保持为 'test'。
  2. 变量 b:作为引用值(函数对象)传入函数,形参 n 获得了 b 的内存地址。n.a = 'change' 修改了该地址指向的对象属性。因此,外部变量 b 的属性 a 会被更新为 'change'。

总结而言,JavaScript 的赋值与传参机制统一且严格:栈内存负责存储原始值和对象指针,堆内存负责存储实际对象。操作时需时刻警惕引用共享带来的副作用,特别是在处理复杂对象时。

以上就是 JavaScript 赋值机制与参数传递的详细内容,更多关于 JavaScript 基础教程的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。