本教程解释 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
变量的值,因为 x
和 y
是单独的变量。
最后,在 square()
函数完成后 y
变量的值不会改变。
如果 JavaScript 使用按引用传递,y
变量的值会在调用 square()
函数后修改为 100
。
按引用传递
不明显看出引用值也是按值传递的。例如:
let person = {
name: 'John',
age: 25,
};
function increaseAge(obj) {
obj.age += 1;
}
increaseAge(person);
console.log(person);
代码是如何工作:
首先,定义 person
对象,它具有两个属性 name
和 age
:
接下来,定义 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 的局部变量。