JavaScript 函数参数传递机制解析:值传递与引用传递的本质

作者:代码拾荒时间:2026-10-30 12:37:45浏览:430

本文深入解析 JavaScript 函数参数传递机制,澄清常见的值传递与引用传递误区。通过基本类型与对象类型的代码示例,说明 JS 采用“共享传值”模式:基本类型复制值,对象类型复制引用地址。修改对象属性影响原对象,但重新赋值不影响外部变量,从而准确理解其底层行为。

JavaScript 参数传递机制概述

在传统认知中,许多人认为 JavaScript 函数传递的是引用(或指针),也有观点认为它同时具备值传递和引用传递的特征。那么 JavaScript 的参数传递机制究竟如何?事实上,以下演示的逻辑同样适用于 Java 等语言。

基本类型参数传递分析

首先来看基本类型的传递情况:


function add(num){
  num+=10;
  return num;
}
num=10;
alert(add(num));
aelrt(num);
//输出20,10

对于上述输出结果 20 和 10,根据 JavaScript 的官方解释,基本类型参数传递时执行了栈帧拷贝操作。此时,外部声明的变量 num 与函数内部的参数 num 拥有完全相同的值,但拥有完全不同的内存地址,两者互不干扰。当函数调用返回时,函数内部的参数 num 栈帧被弹出,因此修改函数内的参数 num 不会影响外部原有的变量。

对象引用类型传递分析

接下来分析较为复杂的对象引用类型传递:


function setName(obj){
  obj.name="ted";
}
var obj=new Object();
setName(obj);
alert(obj.name);
//输出ted

上述代码运行的实质是:创建一个 object 对象,将其引用赋给变量 obj(在 C 语言中这相当于直接赋值内存地址)。在传递函数参数时,执行了与前述方法相同的操作,即复制一个栈帧给函数参数的 obj。此时,两者拥有相同的值(可理解为指向 object 对象的地址)。在调用 setName 方法进行修改时,实际上改变的是 object 对象自身的属性值(在 Java 中称为可变类)。修改完成后,同样会弹出函数参数 obj 对应的栈帧。

因此,最终输出的是修改后的 object 对象属性值。

引用与指针的区别

此时可能有人疑问:这是否也可以理解为引用传递(指针传递)?并非如此。严格来说,在与 Java 类似的语言中,已不再存在传统意义上的指针。在 Java 中,上述过程被称为从符号引用到直接引用的解析过程。在 C 语言中,指针是具有固定长度的类型(多数 C 编译器中为 2 字节),但在 Java 等语言中,引用拥有自己的属性和方法,只是用户无法直接访问和控制它。因此,从某种意义上讲,引用也是一种对象,这种机制在很大程度上避免了内存泄露,术语称之为内存结构化访问机制。

重新赋值对引用的影响

为了验证上述观点,对前述示例进行适当改造:


function setName(obj){
  obj.name="ted";
  obj=new Object();
  obj.name="marry";
}
var obj=new Object();
setName(obj);
alert(obj.name);
//输出ted

该示例与前一个示例的唯一区别在于,此处将一个新的对象赋给了函数参数 obj。这使得函数内部的参数 obj 与外部的引用 obj 拥有完全不同的值和内存地址。

以上关于 JavaScript 函数参数传递机制的解析即为全部内容,希望能为大家提供参考。

作者最新文章