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

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


当前回答

字符串、数字等基本类型变量始终作为传递按价值计算。基于这两个条件,数组和对象作为引用传递或值传递。如果要使用新的Object或array更改该Object或array的值,则它将通过value传递。object1={item:“car”};数组1=[1,2,3];此处是将新对象或数组分配给旧对象或数组。您没有更改属性的值旧对象的。因此它是按值传递的。如果要更改对象或数组的属性值,则会通过引用传递。object1.key1=“汽车”;阵列1[0]=9;此处您正在更改旧对象的属性值。您没有将新对象或数组分配给旧对象或数组。因此它是通过引用传递的。

Code

    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

其他回答

MDN文档对其进行了清晰的解释,但并不过于冗长:

函数调用的参数是函数的参数。参数按值传递给函数。如果功能发生变化参数的值,此更改不会在全局或调用函数。但是,对象引用也是值,并且它们是特殊的:如果函数更改引用对象的财产,该更改在函数外部可见,(…)

资料来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Description

这样想:它总是通过价值传递。然而,对象的值不是对象本身,而是对该对象的引用。

下面是一个例子,传递一个数字(一个原始类型)

function changePrimitive(val) {
    // At this point there are two '10's in memory.
    // Changing one won't affect the other
    val = val * 10;
}
var x = 10;
changePrimitive(x);
// x === 10

对对象重复此操作会产生不同的结果:

function changeObject(obj) {
    // At this point there are two references (x and obj) in memory,
    // but these both point to the same object.
    // changing the object will change the underlying object that
    // x and obj both hold a reference to.
    obj.val = obj.val * 10;
}
var x = { val: 10 };
changeObject(x);
// x === { val: 100 }

再举一个例子:

function changeObject(obj) {
    // Again there are two references (x and obj) in memory,
    // these both point to the same object.
    // now we create a completely new object and assign it.
    // obj's reference now points to the new object.
    // x's reference doesn't change.
    obj = { val: 100 };
}
var x = { val: 10 };
changeObject(x);
// x === { val: 10}

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

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

(摘自上述文章。)

确定某个对象是否“通过引用传递”的一个简单方法是您是否可以编写“交换”函数。例如,在C中,您可以执行以下操作:

void swap(int *i, int *j)
{
    int t;
    t = *i;
    *i = *j;
    *j = t;
}

如果你不能在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" }

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