【问题标题】:How exactly does Javascript pass arguments?Javascript 究竟是如何传递参数的?
【发布时间】:2013-09-27 09:37:47
【问题描述】:

有一个小测试。我希望两个obj\d 对象最终都会改变他们的a 成员。但是change1 样式不起作用,我想知道为什么或为什么不应该这样?

<button id="btn1" onclick="test()">Change</button>
<script>
    var obj1 = { a : {strblahblah: "blah"} };
    var obj2 = { a : {strblahblah: "blah"} };
    function test(){
        change1(obj1.a);
        change2(obj2);
        alert("obj1: " + obj1.toSource() + "\r\nobj2: " + obj2.toSource());
    }

    function change1(obj){
        obj = {str: "change1"};
    }
    function change2(obj){
        obj.a = {str: "change2"};
    }
</script>

结果(点击按钮后):

obj1: ({a:{strblahblah:"blah"}})
obj2: ({a:{str:"change2"}})

【问题讨论】:

  • 在 change1 中忘记了 obj.a
  • @simonzack OP 将a 作为参数传递给change1。它认为这是问题的基础(通过引用或值传递的javascript)。

标签: javascript function arguments


【解决方案1】:

change1 中发生的事情是 obj 最初持有对 obj1.a 中对象的引用。但是,该行:

obj = {str: "change1"};

不会改变obj1.a。相反,它会创建一个新对象 ({str: "change1"}) 并更改 obj,使其现在指向该对象而不是 obj1.a

相比之下,change2 具有 obj 最初持有对 obj2 中对象的引用,并且具有以下行:

obj.a = {str: "change2"};

它访问被引用对象的内部结构(即obj2)并因此对该对象进行实际更改。

【讨论】:

  • 呃,参考,现在我可以更好地理解它了,但是,有什么办法可以做到change1这样的事情吗?因为我想修改obj\da,但又不想将obj\d本身暴露给change方法
  • 我想也许你想要这样的东西:stackoverflow.com/questions/8421605/…
【解决方案2】:

当您将obj1.a 传递给change1() 时,您发送的是obj1.a 的值,它本身就是另一个对象。但是当您将obj2 发送到change2() 时,它会获取对象的引用,并且当您分配值时,原始值会发生变化,而在第一种情况下这并没有发生。

正如thg437 所建议的那样,这最好地解释了这种情况,

Is JavaScript a pass-by-reference or pass-by-value language?

【讨论】:

    【解决方案3】:

    来自MDN

    函数调用的参数是函数的参数。 参数按值传递给函数。如果功能改变 参数的值,此更改不会反映在全局或 调用函数。但是,对象引用也是值,并且 它们是特殊的:如果函数改变了引用对象的 属性,该更改在函数外部可见

    在 change1 中,您传递的是 obj.a,它实际上是一个值(因为它是一个对象引用,而不是对象本身)。这意味着您会在change1 中收到该引用的副本,然后将其修改为指向新对象。您所做的只是修改传递给函数的引用副本,以便它有效地指向内存中的其他内容。

    change2 中,您传递了obj,它也是一个对象引用,但是您随后修改了该引用的a 属性,因此您将获得引用指向的对象并进行修改它的a 属性。这个被修改的对象与您在函数中按值接收的对象引用的副本和代码顶部的引用 obj1 所指向的对象相同。

    【讨论】:

      【解决方案4】:

      此声明obj = {str: "change1"}; 导致obj 引用传递的参数以外的其他内容,

      obj.a = {str: "change2"}; 导致传递参数中的“a”属性更改为其他内容。

      预计,在第一种情况下,您只是在更改输入的引用,而在其他情况下,您实际上是在修改输入参数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-09
        • 2013-07-06
        • 2013-05-20
        • 1970-01-01
        • 2018-06-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多