myfreax

JavaScript 按值传递与按引用传递

本教程解释 JavaScript 按值传递的工作原理,并为您提供了一些将原始值和引用值传递给函数的示例

JavaScript 按值传递与按引用传递
JavaScript 按值传递与按引用传递

本教程解释 JavaScript 按值传递的工作原理,并为您提供了一些将原始值和引用值传递给函数的示例。

在继续学习本教程之前,您应该对原始值和参考值以及它们之间的区别有很好的了解。

JavaScript 按值传递或按引用传递

在 JavaScript 中,所有函数参数始终按值传递。这意味着 JavaScript 将变量的值复制到函数参数中。

您对函数内部参数所做的任何修改都不会响应函数外部传递的变量。换句话说,对参数所做的修改不会反映在函数外部。

如果函数参数通过引用传递,则传递给函数的变量的修改将反映在函数外部。这在 JavaScript 中是不可能的。

按值传递

让我们看看下面的例子。

function square(x) {
    x = x * x;
    return x;
}

let y = 10;
let result = square(y);

console.log(result); // 100 
console.log(y); // 10 -- no change

代码是如何工作的。

首先,定义函数 square() 接受一个参数 x 。该函数将 x 的平方赋值给 x 参数,然后返回 x 的值。

接下来,声明变量 y 并将其值初始化为 10

然后,将 y 变量传递给 square() 函数。在 y 变量传递给 square() 函数时,JavaScript 会复制 y 变量值到 x 变量。

之后,square() 函数修改 x 变量。但是,它不会影响 y 变量的值,因为 xy 是单独的变量。

最后,在 square() 函数完成后 y 变量的值不会改变。

如果 JavaScript 使用按引用传递,y 变量的值会在调用 square()  函数后修改为 100

按引用传递

不明显看出引用值也是按值传递的。例如:

let person = {
  name: 'John',
  age: 25,
};

function increaseAge(obj) {
  obj.age += 1;
}

increaseAge(person);

console.log(person);

代码是如何工作:

首先,定义 person对象,它具有两个属性 nameage

接下来,定义 increaseAge() 接受对象obj并将参数age的属性增加obj一的函数。

接下来,定义 increaseAge() 函数,它接受一个对象 obj 并将 obj 的属性 age 属性增加一。

然后,将对象 person 传递给 increaseAge() 函数:

在内部,JavaScript 引擎创建 obj 引用并使此变量引用与 person 变量引用的对象相同。

之后,在 increaseAge() 函数内部将 obj 变量的 age 属性增加 1。

最后,通过 person 引用访问对象:

看起来 JavaScript 通过引用传递对象,因为对对象的修改反映在函数外部。然而,这种情况并非如此。

事实上,将对象传递给函数时,传递的是对象的引用,而不是实际对象。因此,函数可以通过其引用修改对象的属性。

但是,您不能修改传递给函数的引用。例如:

let person = {
  name: 'John',
  age: 25,
};

function increaseAge(obj) {
  obj.age += 1;

  // reference another object
  obj = { name: 'Jane', age: 22 };
}

increaseAge(person);

console.log(person);

输出:

{ name: 'John', age: 26 }

在此示例中,increaseAage() 函数 obj 对象的 age 属性。

并使 obj 引用成为另一个对象:

但是 person 一直引用原始对象的 age 被增加到 26,换句话说, increaseAge() 函数不会改变 person 的引用。

如果这个概念仍然让您感到困惑,您可以将函数参数视为局部变量。

结论

  • JavaScript 按值将所有参数传递给函数。
  • 函数参数是 JavaScript 的局部变量。

内容导航