Javascript究竟如何传递参数?

时间:2013-09-27 09:37:48

标签: javascript function arguments

有一个小测试。我希望两个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"}})

4 个答案:

答案 0 :(得分:2)

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

obj = {str: "change1"};

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

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

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

访问引用对象的内部结构(即obj2),从而对该对象进行实际更改。

答案 1 :(得分:1)

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

正如thg437建议的那样,这最好地解释了这个案例,

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

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

来自MDN

  

函数调用的参数是函数的参数。   参数按值传递给函数。如果功能改变了   参数的值,这种变化不会全局或反映   调用功能。但是,对象引用也是值,和   它们很特别:如果函数改变了引用的对象   属性,该变化在函数外可见

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

change2中,您传递obj也是一个对象引用,但是您正在修改该引用的a属性,因此您将获得指向的对象通过引用并修改其a属性。修改的此对象与函数中的值和代码顶部的引用obj1所接收的对象引用的副本所指向的对象相同。