基元类型(数字、字符串等)是通过值传递的,但对象是未知的,因为它们既可以通过值传递(如果我们认为持有对象的变量实际上是对对象的引用),也可以通过引用传递(当我们认为对象的变量持有对象本身)。

虽然最后这并不重要,但我想知道通过约定来表达论点的正确方式是什么。是否有JavaScript规范的摘录,该规范定义了与此相关的语义?


当前回答

函数内部的简单值不会改变函数外部的值(通过值传递),而复杂值会(通过引用传递)。

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

其他回答

嗯,这是关于“性能”和“速度”的,在编程语言中,简单地说就是“内存管理”。

在javascript中,我们可以将值放在两层:type1对象和type2所有其他类型的值,如字符串和布尔值等

如果你把记忆想象成下面的方块,其中每个方块中只能保存一个type2值:

每个type2值(绿色)是一个正方形,而type1值(蓝色)是它们的一组:

重点是,如果你想指示一个type2值,地址是很简单的,但如果你想对type1值做同样的事情,那根本不容易!:

在一个更复杂的故事中:

所以这里的参考资料可以拯救我们:

虽然这里的绿色箭头是一个典型变量,但紫色箭头是对象变量,所以因为绿色箭头(典型变量)只有一个任务(这表示一个典型值),所以我们不需要将它的值与它分开,所以我们将绿色箭头与它的值一起移动到任何位置,在所有赋值、函数等中。。。

但我们不能用紫色箭头做同样的事情,我们可能想把“约翰”牢房搬到这里或其他很多事情。。。,所以紫色的箭头会固定在它的位置上,而分配给它的典型箭头会移动。。。

一个非常令人困惑的情况是,您无法意识到引用的变量是如何变化的,让我们来看一个非常好的例子:

let arr = [1, 2, 3, 4, 5]; //arr is an object now and a purple arrow is indicating it
let obj2 = arr; // now, obj2 is another purple arrow that is indicating the value of arr obj
let obj3 = ['a', 'b', 'c'];
obj2.push(6); // first pic below - making a new hand for the blue circle to point the 6
//obj2 = [1, 2, 3, 4, 5, 6]
//arr = [1, 2, 3, 4, 5, 6]
//we changed the blue circle object value (type1-value) and due to arr and obj2 are indicating that so both of them changed
obj2 = obj3; //next pic below - changing the direction of obj2 array from blue circle to orange circle so obj2 is no more [1,2,3,4,5,6] and it's no more about changing anything in it but we completely changed its direction and now obj2 is pointing to obj3
//obj2 = ['a', 'b', 'c'];
//obj3 = ['a', 'b', 'c'];

JavaScript总是按值传递;一切都是价值型的。

对象是值,对象的成员函数本身是值(请记住,函数是JavaScript中的一级对象)。此外,关于JavaScript中的一切都是一个对象的概念;这是错误的。字符串、符号、数字、布尔值、空值和未定义值都是基元。

有时,他们可以利用从基本原型继承的一些成员函数和财产,但这只是为了方便。这并不意味着它们本身就是对象。请尝试以下操作以供参考:

x=“测试”;console.log(x.foo);x.foo=12;console.log(x.foo);

在两个console.log中,您都会发现值未定义。

变量不“保存”对象;它有一个参考。您可以将该引用分配给另一个变量,现在两者都引用同一个对象。它总是按值传递(即使该值是引用…)。

无法更改作为参数传递的变量所持有的值,如果JavaScript支持通过引用传递,这是可能的。

我理解这一点的简单方法。。。

调用函数时,您将传递内容(引用或值),而不是变量本身。var var1=13;var var2={prop:2};//13和var2的内容(引用)正在此处传递foo(var1,var2);在函数内部,参数变量inVar1和inVar2接收传递的内容。函数foo(inVar1,inVar2){//更改inVar1和inVar2的内容不会影响外部变量inVar1=20;inVar2={prop:7};}由于inVar2收到了{prop:2}的引用,因此可以更改对象属性的值。函数foo(inVar1,inVar2){inVar2.prop=7;}

函数内部的简单值不会改变函数外部的值(通过值传递),而复杂值会(通过引用传递)。

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