基元类型(数字、字符串等)是通过值传递的,但对象是未知的,因为它们既可以通过值传递(如果我们认为持有对象的变量实际上是对对象的引用),也可以通过引用传递(当我们认为对象的变量持有对象本身)。
虽然最后这并不重要,但我想知道通过约定来表达论点的正确方式是什么。是否有JavaScript规范的摘录,该规范定义了与此相关的语义?
基元类型(数字、字符串等)是通过值传递的,但对象是未知的,因为它们既可以通过值传递(如果我们认为持有对象的变量实际上是对对象的引用),也可以通过引用传递(当我们认为对象的变量持有对象本身)。
虽然最后这并不重要,但我想知道通过约定来表达论点的正确方式是什么。是否有JavaScript规范的摘录,该规范定义了与此相关的语义?
当前回答
MDN文档对其进行了清晰的解释,但并不过于冗长:
函数调用的参数是函数的参数。参数按值传递给函数。如果功能发生变化参数的值,此更改不会在全局或调用函数。但是,对象引用也是值,并且它们是特殊的:如果函数更改引用对象的财产,该更改在函数外部可见,(…)
资料来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Description
其他回答
JavaScript按值传递原语类型,按引用传递对象类型
现在,人们喜欢没完没了地争论是否“通过引用”是描述Java等实际操作的正确方式这是:传递对象不会复制对象。传递给函数的对象可以由该函数修改其成员。传递给函数的基元值不能由该函数修改。复制完成。在我的书中,这叫做通过引用传递。
-Brian Bi-哪些编程语言是通过引用传递的?
使现代化
以下是对此的反驳:
JavaScript中没有可用的“通过引用传递”。
分享我对JavaScript中引用的了解
在JavaScript中,当将对象分配给变量时,分配给变量的值是对对象的引用:
变量a={a: 1中,b: 2,c: 3个};变量b=a;//b.c是指交流值console.log(b.c)//输出:3//更改b.c值b.c=4//也会更改交流值console.log(a.c)//输出:4
这是对值传递和引用传递(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" }
等号(=)运算符设置新的内存空间或地址
在低级语言中,如果要通过引用传递变量,则必须在创建函数时使用特定语法:
int myAge = 14;
increaseAgeByRef(myAge);
function increaseAgeByRef(int &age) {
*age = *age + 1;
}
&age是对myAge的引用,但如果您需要该值,则必须使用*age转换引用。
JavaScript是一种高级语言,可以为您进行这种转换。
因此,尽管对象是通过引用传递的,但语言将引用参数转换为值。您不需要在函数定义上使用&来通过引用传递它,也不需要在功能体上使用*来将引用转换为值,JavaScript会为您执行此操作。
这就是为什么当您试图通过替换函数中的对象的值(即age={value:5})来更改该对象时,更改不会持久,但如果您更改了它的财产(即age.value=5),更改就会持久。
了解更多信息
一切都是通过价值传递的。
基本类型按值传递(即,实际变量值的新副本传递给函数)。
复杂类型(对象)作为“对象指针”传递。因此,您传递的实际内容是一个指针,它是按值传递的(它是一个地址,一个像任何其他值一样的数值)。显然,如果您试图在函数内修改对象的属性,那么即使在该函数外,修改也会反映出来。这是因为您通过指向属性唯一副本的指针访问属性。
这里的混淆出现在“通过值传递指针”和“通过引用传递对象”上。