原始类型(例如数字、字符串等)通过值传递,但对象不同,因为它们既可以按值传递(在这种情况下,我们认为保存对象的变量实际上是对该对象的引用),也可以按引用传递(当我们认为变量对对象本身持有该对象时)。
虽然最终并不重要,但我想知道呈现参数传递约定的正确方式是什么。是否有来自JavaScript规范的节选,定义了关于此事应该是什么语义?
原始类型(例如数字、字符串等)通过值传递,但对象不同,因为它们既可以按值传递(在这种情况下,我们认为保存对象的变量实际上是对该对象的引用),也可以按引用传递(当我们认为变量对对象本身持有该对象时)。
虽然最终并不重要,但我想知道呈现参数传递约定的正确方式是什么。是否有来自JavaScript规范的节选,定义了关于此事应该是什么语义?
判断一个变量是否是“按引用传递”的简单方法是看你是否可以编写一个“交换”函数。例如,在C语言中,你可以这样做:
void swap(int *i, int *j)
{
int t;
t = *i;
*i = *j;
*j = t;
}
数组和对象根据以下两个条件之一进行按引用传递或按值传递。
如果您使用新对象或数组更改该对象或数组的值,则它将按值传递。
object1 = {item: "car"};
array1=[1,2,3];
在这里,您将新对象或数组分配给旧对象。您没有更改旧对象的属性值,因此它是按值传递。
如果您更改对象或数组的属性值,则它将按引用传递。
object1.key1= "car";
array1[0]=9;
在这里,您更改了旧对象的属性值。您没有将新对象或数组分配给旧对象,因此它是按引用传递。
代码
function passVar(object1, object2, number1) {
object1.key1= "laptop";
object2 = {
key2: "computer"
};
number1 = number1 + 1;
}
var object1 = {
key1: "car"
};
var object2 = {
key2: "bike"
};
var number1 = 10;
passVar(object1, object2, number1);
console.log(object1.key1);
console.log(object2.key2);
console.log(number1);
Output: -
laptop
bike
10
原始类型按值传递,而对象按引用传递。这与其他语言(如C、Visual Basic或Delphi)非常不同。我无法确切地说它们如何处理对象和原始类型,但我知道Visual Basic和Delphi可以(并且应该)指定。
自版本5以来,PHP做了类似的事情:所有对象都是按引用传递的,但如果在原始类型之前加上一个&符号,那么所有原始类型可能也会被按引用传递。否则,原始类型将按值传递。
因此,在JavaScript中,如果我通过参数将对象X传递到函数中,它仍然是X。如果您在函数内部更改数据(或任何其他对象,但这并不重要),则该新值也可在函数外部使用。
函数内的简单值不会改变函数外的那些值(它们是按值传递的),而复杂值会改变(它们是按引用传递的)。
function willNotChange(x) {
x = 1;
}
var x = 1000;
willNotChange(x);
document.write('After function call, x = ' + x + '<br>'); // Still 1000
function willChange(y) {
y.num = 2;
}
var y = {num: 2000};
willChange(y);
document.write('After function call y.num = ' + y.num + '<br>'); // Now 2, not 2000
var x=3, y=x; f(x); alert(y === x);
,那么函数f()
可以使得alert
报告false
而不是true
。在JavaScript中,这是不可能的,所以它不是“按引用传递”。能够传递可修改对象的引用是好的,但这并不是“按引用传递”的意思。就像我说的,术语混淆真是令人遗憾。 - Pointy