【问题标题】:Is there thing like pass by value pass by reference in JavaScript?在 JavaScript 中是否有类似传值传引用的东西?
【发布时间】:2016-06-11 23:46:08
【问题描述】:

当我开始学习 C++ 中的函数时,它是通过值和引用传递的。 我们在 javascript 中有类似的东西吗?

如果是/不是,如果是 javascript,它是如何工作的?

谢谢大家。

【问题讨论】:

标签: javascript


【解决方案1】:

这个问题的其他答案是正确的 - 所有变量在 JavaScript 中都是按值传递的,有时该值指向一个对象。

当编程语言支持通过引用传递时,可以从函数内部更改变量指向的位置。这在 JavaScript 中是不可能的。

例如,考虑以下代码,它试图将传递的变量重新分配给一个新值:

function changeCaller( x ) {
    x = "bar";  // Ha ha!
}

function testChangeCaller() {

    var x = "foo";

    changeCaller(x);

    alert(x); // still "foo"

}

testChangeCaller();

尝试将变量指向新对象会失败,就像上面的示例无法重新分配原始字符串一样:

function changeCaller( x ) {
    x = new Object(); // no longer pointing to the same object
    x.a = "bar";
}

function testChangeCaller() {

    var x = new Object();
    x.a = "foo";

    changeCaller(x);

    alert(x.a); // still "foo"

}

testChangeCaller();

让人们相信他们正在处理传递引用场景的特性是在修改对象时。您可以对对象或数组进行更改,因为局部变量指向同一个对象

function changeCaller( x ) {
    x.a = "bar";
}

function testChangeCaller() {

    var x = new Object();
    x.a = "foo";

    changeCaller(x);

    alert(x.a); // now "bar", since changeCaller worked on the same object

}

testChangeCaller();

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    JavaScript 总是按值传递,从不按引用传递。由于对象的工作方式,很多人对此感到困惑。

    对于 JavaScript 中的任何变量都没有“通过引用传递”(不,即使将对象分配给该变量也没有)。所有变量和参数都按值分配。如果分配的值是一个对象,那么新变量的值是对该对象的引用,但是将新值/对象分配给新变量不会影响原始变量。

    有些人将这种行为称为传递“引用值”

    比较 - PHP

    $foo = "foo";
    $bar = &$foo;  // assign by reference
    $bar = "bar";
    echo $foo; // -> output: "bar"
    

    JavaScript

    foo = {"foo": true};
    bar = foo;     // assign value by reference
    bar = {"bar": true};
    alert(JSON.stringify(foo)); // -> output: '{"foo": true}
    

    【讨论】:

    • 出于所有意图和目的,对象(包括数组)通过引用传递。说“你是通过值传递,但值是对对象的引用”是另一种说法“你是通过引用传递”。除非你只是想迷惑别人。
    • @rob,并非出于所有的意图和目的。例如,许多 WMI 脚本调用要求您通过引用将变量传递给函数,以便该函数的返回值可以是错误号。它没有返回结果,而是将结果分配给传入的变量。VBScript 可以很好地处理这个问题,但 JScript/JavaScript 不能,因为它不能传递对变量的引用。它们不是一回事,我没有尝试为了迷惑人们,我试图通过消除已经引起很多混乱的神话来消除人们的迷惑。
    • 不,@rob,事实并非如此。传递的 value 是引用的值。在真正的按引用传递语言中,编译器引入了一个在代码中不可见的指针。在传递引用的语言中,您可以自然地编写臭名昭著的“交换两个整数”函数。 Javascript 中变量的值是always 对对象的引用,当您调用函数时,您会always 传递该值。如果 Number 上有允许更改值的方法,也许会更清楚。
    • @rob:当然可以,您误解了答案和 cmets。点变量的值是对对象的引用,但点本身并不是对传入变量的引用。通过引用传递的方式不同,如果在函数内部设置point = "a string and not an object";,则原始变量传递给函数的内容将被修改。在 JavaScript 中,情况并非如此。按引用传递和按引用传递值不是一回事。
    • @joeframbach:是的。 b 被分配了对a 也引用的同一对象的引用。也就是说,两个变量都持有对同一个对象的引用,但b 不是对a 的引用。对于真正的引用传递,b = false 也会改变a 的值。将 PHP 示例(按引用分配/传递)与 JavaScript 示例(按值分配/传递引用)进行比较。
    【解决方案3】:

    关于讨论,除了 Pointy 注释之外,关于“价值”和“参考”的考虑是错误的。 Javascript 与 c# 或 java 等其他引用语言一样,不会将变量本身的引用传递给方法,而是将变量引用的对象的引用传递给方法。 这里的人们所期望的是,将指针传递给引用对象的变量,指针传递与引用传递不同,并且肯定与值传递不同。

    这里预期的行为是指针传递。 通过引用传递将引用发送到对象。 传值拷贝存储在变量中的对象,并传递拷贝 方法。

    【讨论】:

      【解决方案4】:

      按值传递、按引用传递的讨论是一个邪恶的模因。 Java 讨论中也出现了这种邪恶的模因。

      很简单:将值的位模式复制到参数中。位模式是 int 还是对象的地址都没有关系——它只是被逐位复制到参数中。再简单不过了。运行时并没有为原语和引用做一些特别的事情。它只是简单地并且总是复制该值。

      对此的计算机科学术语是“按值传递”。

      通过引用传递只是不再用于编程。在像 Pascal 这样的旧语言中,您可以编写一个函数来直接更改调用例程中的值。因此,例如,调用例程中的 int 变量可以在被调用函数中更改。

      【讨论】:

        【解决方案5】:

        原始值通过值传递,对象通过引用传递。

        字符串是不可变的,因此尽管它们被视为原始类型,但它们是通过引用传递的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-18
          • 2018-04-13
          • 2020-01-25
          • 2021-09-29
          • 2016-10-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多