【问题标题】:Javascript passing by reference instead of value? [duplicate]Javascript通过引用而不是值传递? [复制]
【发布时间】:2013-07-23 04:14:05
【问题描述】:

您好,感谢您的帮助

当我编写一些代码时,我遇到了一个问题。在下面的例子中。我期待alert(a.x) 输出1,而不是输出2。我了解到这是因为a 被传递给this.b 作为参考。我似乎找不到的是如何通过值传递它。 (如,我不想每次调用x()时都修改a

var a = {"x":1}

function x() {
  this.b = v;
  this.b.x++;
}

x();

alert(a.x); //prints 2

我也尝试了以下和其他变体无济于事......

var a = {"x":1}

function x(v) {
  this.b = v;
  this.b.x++;
}

x(a);

alert(a.x); //... still prints 2

谁能告诉我我错过了什么?

请,谢谢

(旁注:this is a post 这与我所说的很接近,但我不知道如何使它适用于我的情况......如果情况完全一样的话)

【问题讨论】:

    标签: javascript pass-by-reference pass-by-value


    【解决方案1】:

    所以也许我可以通过分解正在发生的事情来为您提供一些清晰的信息。

    var a = {"x":1} // a refers to object with key "x"
    
    function x(v) {  // v is now a reference to the object with key "x"
      this.b = v;   // this.b now is a reference to the object with key "x"
      this.b.x++;   //this.b.x++ points to the object with key "x" so it can increment it's value.
    }
    
    x(a);  // passes in a the value of reference to object with key "x"
    
    alert(a.x); //... still prints 2
    

    你可以做一些可以在this链接中找到的事情:

    var o = {};
    (function(x){
        var obj = Object.create( x );
        obj.foo = 'foo';
        obj.bar = 'bar';
    })(o);
    
    alert( o.foo ); // undefined
    

    【讨论】:

      【解决方案2】:

      当你打电话时:

      x(a);
      

      正在发生一些事情。首先,变量a(它只是保存一个对象的引用)按值传递给函数xx 现在拥有该引用的自己的副本,它恰好指向内存中的同一个对象。因此,您对该引用对象的属性所做的任何更改都会影响对该对象的其他引用。

      当你打电话时:

      this.b = v;
      

      您再次制作了v 的副本并将其设置为this.b。现在,avthis.b 是内存中不同的变量,它们都存储对同一对象的引用。

      看来您尝试要做的是创建对象本身的副本,这样您就可以操纵一个引用而不影响其他引用。为此,您需要在内存中创建一个全新的对象并复制属性。

      var a = {"x":1}
      
      function x(v) {
          this.b = {}; // Create a new object
          this.b.x = v.x; // Copy over the x property
          // Copy over any other properties too
          this.b.x++;
      }
      
      x(a);
      
      alert(a.x); // The original object still has an x property of 1
      

      由于this.b 是一个新对象,我们只是从v 引用的对象中复制属性,因此增加this.b.x 将不会影响v 是什么指向。

      【讨论】:

      • 通过引用意味着分配对调用者可见,这里只有突变对调用者可见。调用者不会看到非对象中的突变,因为无论如何您都无法改变它们。它总是按值传递。
      • 通过 reference,我的意思是该对象的一个​​副本将存在于内存中,并且对该位置的 reference 将被传递。跨度>
      • @mike。在您的第一个示例中,为什么当您将a.x 传递给x(v) 时,您可以设置this.b.x = v.x 而不是仅this.b.x = v?这个问题有意义吗?
      • @bobkingof12vs - 你不能。参数v 等于一个数值(在本例中为 1)。数值没有没有x属性(如果你访问它,你只会得到undefined
      • 我想我的问题更多,在你的例子中:function x(v) { this.b = v; this.b.x++; } 你从哪里得到this.b.x
      猜你喜欢
      • 2021-05-20
      • 1970-01-01
      • 2011-05-25
      • 1970-01-01
      • 2020-04-01
      • 2013-05-22
      相关资源
      最近更新 更多