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

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


当前回答

“JavaScript:最终指南”一书的这一章对复制、传递和比较值和引用进行了非常详细的解释。

在我们离开主题之前操作对象和阵列参考,我们需要澄清一点术语。短语“路过”“引用”可以有几种含义。对一些读者来说,这个短语指的是一种函数调用技术允许函数分配新值它的论点,并拥有这些外部可见的修改值作用这不是术语的方式本书中使用了。这里,我们的意思是简单地说,对对象的引用或数组--而不是对象本身--传递给函数。A函数可以使用引用修改对象或元素的财产阵列的。但如果函数用对新对象或阵列的引用,该修改不可见在功能之外。读者熟悉这个词可能更喜欢这样说对象和数组值,但传递的值为实际上是一个参考,而不是对象本身。

其他回答

我在AirBNB风格指南中找到了最简洁的解释:

基本体:访问基本体类型时,直接处理其价值一串数字布尔型无效的未定义

例如。:

var foo = 1,
    bar = foo;

bar = 9;

console.log(foo, bar); // => 1, 9

复杂:访问复杂类型时,需要处理对其值的引用对象大堆作用

例如。:

var foo = [1, 2],
    bar = foo;

bar[0] = 9;

console.log(foo[0], bar[0]); // => 9, 9

也就是说,基本类型是通过值传递的,复杂类型是通过引用传递的。

字符串、数字等基本类型变量始终作为传递按价值计算。基于这两个条件,数组和对象作为引用传递或值传递。如果要使用新的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

基本体通过值传递,对象通过引用传递。这与C、Visual Basic或Delphi等其他语言截然不同。我不能说它们如何准确地处理对象和原语,但我知道VisualBasic和Delphi可以(也应该)指定它们。

PHP在版本5之后做了类似的事情:所有对象都是通过引用传递的,但所有原语都可以通过引用传递,如果前面有一个与符号(&)。否则,基元按值传递。

所以在JavaScript中,如果我通过一个参数将一个对象X传递给一个函数,它仍然是X。如果你在函数(或任何其他对象,但这并不重要)内部更改数据,那么新值也可以在函数外部使用。

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

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

如果你不能在JavaScript中做到这一点,那就不是“通过引用传递”。

我会说这是通过复印件传递的-

考虑参数和变量对象是在函数调用开始时创建的执行上下文中创建的对象,传递到函数中的实际值/引用只存储在这个参数+变量对象中。

简单地说,对于基元类型,值在函数调用开始时被复制,对于对象类型,引用被复制。