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

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


当前回答

这里有一些关于JavaScript中使用术语“通过引用传递”的讨论,但要回答您的问题:

对象通过引用自动传递,无需特别声明

(摘自上述文章。)

其他回答

它总是按值传递,但对于对象,变量的值是一个引用。因此,当您传递一个对象并更改其成员时,这些更改将在函数之外持续存在。这使得它看起来像是通过引用传递。但如果您实际更改了对象变量的值,您将看到更改不会持续,这证明它确实是通过值传递的。

例子:

函数changeObject(x){x={member:“bar”};console.log(“in changeObject:”+x.member);}函数changeMember(x){x.member=“bar”;console.log(“in changeMember:”+x.member);}var x={member:“foo”};console.log(“before changeObject:”+x.member);changeObject(x);console.log(“after changeObject:”+x.member);/*更改没有持续*/console.log(“changeMember之前:”+x.member);changeMember(x);console.log(“after changeMember:”+x.member);/*更改持续存在*/

输出:

before changeObject: foo
in changeObject: bar
after changeObject: foo

before changeMember: foo
in changeMember: bar
after changeMember: bar

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

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

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

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

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

在低级语言中,如果要通过引用传递变量,则必须在创建函数时使用特定语法:

int myAge = 14;
increaseAgeByRef(myAge);
function increaseAgeByRef(int &age) {
  *age = *age + 1;
}

&age是对myAge的引用,但如果您需要该值,则必须使用*age转换引用。

JavaScript是一种高级语言,可以为您进行这种转换。

因此,尽管对象是通过引用传递的,但语言将引用参数转换为值。您不需要在函数定义上使用&来通过引用传递它,也不需要在功能体上使用*来将引用转换为值,JavaScript会为您执行此操作。

这就是为什么当您试图通过替换函数中的对象的值(即age={value:5})来更改该对象时,更改不会持久,但如果您更改了它的财产(即age.value=5),更改就会持久。

了解更多信息

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

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

这是对值传递和引用传递(JavaScript)的更多解释。在这个概念中,他们讨论的是通过引用传递变量和通过引用传递该变量。

传递值(基本类型)

var a = 3;
var b = a;

console.log(a); // a = 3
console.log(b); // b = 3

a=4;
console.log(a); // a = 4
console.log(b); // b = 3

应用于JavaScript中的所有基元类型(字符串、数字、布尔值、未定义和null)。a被分配一个存储器(例如0x001),b在存储器中创建该值的拷贝(例如0x002)。因此,更改一个变量的值不会影响另一个变量,因为它们都位于两个不同的位置。


通过引用(对象)

var c = { "name" : "john" };
var d = c;

console.log(c); // { "name" : "john" }
console.log(d); // { "name" : "john" }

c.name = "doe";

console.log(c); // { "name" : "doe" }
console.log(d); // { "name" : "doe" }

JavaScript引擎将对象分配给变量c,并指向某个内存,例如(0x012)。当d=c时,在该步骤中,d指向相同的位置(0x012)。更改任何变量的值都会更改这两个变量的值。函数是对象


特殊情况,通过引用传递(对象)

c = {"name" : "jane"};
console.log(c); // { "name" : "jane" }
console.log(d); // { "name" : "doe" }

等号(=)运算符设置新的内存空间或地址