基元类型(数字、字符串等)是通过值传递的,但对象是未知的,因为它们既可以通过值传递(如果我们认为持有对象的变量实际上是对对象的引用),也可以通过引用传递(当我们认为对象的变量持有对象本身)。
虽然最后这并不重要,但我想知道通过约定来表达论点的正确方式是什么。是否有JavaScript规范的摘录,该规范定义了与此相关的语义?
基元类型(数字、字符串等)是通过值传递的,但对象是未知的,因为它们既可以通过值传递(如果我们认为持有对象的变量实际上是对对象的引用),也可以通过引用传递(当我们认为对象的变量持有对象本身)。
虽然最后这并不重要,但我想知道通过约定来表达论点的正确方式是什么。是否有JavaScript规范的摘录,该规范定义了与此相关的语义?
当前回答
JavaScript总是按值传递;一切都是价值型的。
对象是值,对象的成员函数本身是值(请记住,函数是JavaScript中的一级对象)。此外,关于JavaScript中的一切都是一个对象的概念;这是错误的。字符串、符号、数字、布尔值、空值和未定义值都是基元。
有时,他们可以利用从基本原型继承的一些成员函数和财产,但这只是为了方便。这并不意味着它们本身就是对象。请尝试以下操作以供参考:
x=“测试”;console.log(x.foo);x.foo=12;console.log(x.foo);
在两个console.log中,您都会发现值未定义。
其他回答
我已经多次阅读了这些答案,但直到我了解了Barbara Liskov所称的“通过共享呼叫”的技术定义,我才真正理解
通过共享调用的语义与通过引用调用的语义不同,因为对函数内函数参数的赋值对调用方不可见(与引用语义不同)[需要引用],因此例如,如果传递了变量,则无法在调用方的范围内模拟对该变量的赋值。然而,由于函数可以访问与调用方相同的对象(不进行复制),因此如果对象是可变的,则调用方可以看到函数中这些对象的突变,这可能与逐值调用语义不同。调用方可以看到函数中可变对象的变体,因为该对象未被复制或克隆,而是共享的。
也就是说,如果您访问参数值本身,参数引用是可变的。另一方面,对参数的赋值将在求值后消失,函数调用方无法访问。
MDN文档对其进行了清晰的解释,但并不过于冗长:
函数调用的参数是函数的参数。参数按值传递给函数。如果功能发生变化参数的值,此更改不会在全局或调用函数。但是,对象引用也是值,并且它们是特殊的:如果函数更改引用对象的财产,该更改在函数外部可见,(…)
资料来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Description
我会说这是通过复印件传递的-
考虑参数和变量对象是在函数调用开始时创建的执行上下文中创建的对象,传递到函数中的实际值/引用只存储在这个参数+变量对象中。
简单地说,对于基元类型,值在函数调用开始时被复制,对于对象类型,引用被复制。
我理解这一点的简单方法。。。
调用函数时,您将传递内容(引用或值),而不是变量本身。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;}
这是对值传递和引用传递(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" }
等号(=)运算符设置新的内存空间或地址