函数是编程中最重要的概念之一。在 JavaScript 中,函数作为一等公民,可以被看做是值(变量)的一种特殊类型。函数的传递方式有两种:值传递和引用传递。JavaScript 中函数值的传递是单向传递的,这意味着传递函数的值被复制到参数变量中,而不是参数变量本身,因此在函数中对参数变量所做的任何更改都不会在函数外反映出来。
1. 值传递与引用传递
在 JavaScript 中,基本数据类型(如数字、布尔值和字符串)是通过值传递进行的。例如,下面的代码演示了值传递:
```
let a = 10;
function changeValue(a) {
a = 20;
}
changeValue(a); // a仍然为10
```
在这个例子中,变量 a 作为参数传递到函数 `changeValue()` 中。然而,在函数内部,参数 a 的值被更改为 20,但是函数外部的变量 a 的值仍然是 10。这是因为参数 a 是被复制的,而不是直接引用原始变量 a。
引用传递是一种更复杂的传递方式,它用于对象和数组。在引用传递中,变量包含对象或数组的地址,而不是实际的对象或数组。因此,在函数内对参数对象或数组所做的更改会在函数外部反映出来。例如:
```
let obj = {
name: "Tom"
};
function changeName(obj) {
obj.name = "Jerry";
}
changeName(); // obj.name现在为"Jerry"
```
在这个例子中,变量 obj 包含一个对象的地址。当 `changeName()` 被调用时,参数 obj 中的地址被复制到一个新变量 obj 中,并且该地址引用相同的对象。因此,函数内的代码通过对象引用更改了对象属性,这个更改也反映到函数外部。
2. 函数值的单向传递
尽管 JavaScript 中的对象和数组是通过引用传递进行传递的,但函数值却通过值传递进行传递。这意味着函数参数中包含的函数值是被复制的,而不是直接引用原始函数。这种特性通常被称为“函数值的单向传递”。
例如,考虑以下代码:
```
let fn = function() {
console.log("Hello world!");
};
function callFn(func) {
func();
}
callFn(fn); // 输出 "Hello world!"
```
在这个例子中,函数 `callFn()` 接受一个函数参数,并调用它。然而,即使函数参数 `fn` 被命名为一个已经定义的函数,它仍然是通过值传递进行传递的,而不是直接引用原始函数 `fn`。
这意味着,即使在函数 `callFn()` 内部对函数参数 `fn` 进行了更改,这些更改也不会在函数外部反映出来。例如:
```
let fn = function() {
console.log("Hello world!");
};
function changeFn(func) {
func = function() {
console.log("Goodbye world!");
};
}
changeFn(fn);
fn(); // 输出 "Hello world!"
```
在这个另一个例子中,函数 `changeFn()` 接受一个函数参数,并将其更改为一个新的函数。然而,即使 `fn` 和 `func` 引用相同的函数,函数 `callFn()` 在调用时仍然输出 "Hello world!",而不是 "Goodbye world!"。这是因为函数值被单向传递,而函数 `changeFn()` 对参数 `func` 所做的更改不会影响函数参数 `fn`。
3. 一个单向传递的例子
考虑以下代码:
```
let array = [1, 2, 3];
function reverseArray(arr) {
arr.reverse();
}
reverseArray(array);
console.log(array); // 输出 [3, 2, 1]
```
在这个例子中,我们定义了一个函数 `reverseArray()`,它接受一个数组参数并将其反转。函数 `reverseArray()` 在调用时传递了变量 `array`,该变量包含一个数组的引用。因此,函数 `reverseArray()` 可以通过该引用修改原始数组。
例如,当调用函数 `reverseArray()` 时,参数 `arr` 中的地址被复制到一个新变量 `arr` 中,并且该地址引用相同的数组。随后,函数内调用数组方法 `reverse()`,该方法反转了数组的顺序。因此,当我们在函数外部使用 `console.log(array)` 输出数组时,我们可以看到数组已经被反转了。
4. 结论
在本文中,我们深入研究了 JavaScript 中函数值单向传递的概念。我们看到了传递函数值的两种方法(值传递和引用传递),以及函数值单向传递的含义。此外,我们还通过一个例子说明了函数值单向传递的工作方式。
扫码领取最新备考资料