【问题标题】:Are there any rules of thumb for when JavaScript values are copied by reference and not by value?当 JavaScript 值通过引用而不是值复制时,是否有任何经验法则?
【发布时间】:2012-01-30 18:51:07
【问题描述】:

即使作为一个经验丰富的 JS 开发人员,我也经常对对象的浅拷贝和深拷贝感到惊讶。

对于通过引用而不是主要对象类型的值复制 JavaScript 值时,是否有任何经验法则?例如,我知道字符串值总是通过值而不是引用来复制。

【问题讨论】:

  • 取决于您的复制方法。你必须具体——你如何复制你的价值观?
  • 或者你的意思是当一个值作为参数传递给一个函数的情况?
  • 我想的是一种简单的var x, y; x = { 'blah': 'foo' }; y = x; x = { 'bar': 'bas' }; console.log( y ); 类型的情况,而不是通过参数传递,但如果复制类型有更多细微差别,请告诉我如何改进问题。跨度>
  • 学究式帽子:JavaScript 严格按值传递。
  • @lwburk 好吧,但是当您没有意识到 JavaScript 中有多少 本身就是引用时,就会感到困惑。

标签: javascript


【解决方案1】:

在 JavaScript 中,所有对象都是“通过引用”存储和传递的。

var a = { v: 'a' }, b = { v: 'b' };
a=b;
b.v='c';

ab 将引用同一个对象; a.v == 'c'b.v == 'c'

原始数据类型(stringnumberbooleannullundefined)是不可变的;它们是按值传递的。

var a = 'a', b = 'b';
a=b;
b='c';

由于我们处理的是原语,a == 'b'b == 'c'


Pedants 会告诉你 JavaScript 不是传统意义上的按引用传递,或者它是一种“纯粹的按值传递”语言,但我认为这会使事情变得复杂。不,您不能直接修改传递给函数的参数,就好像它是一个变量一样(如果语言是真正的按引用传递,这将是正确的),但您也不会收到 copy 作为参数传递的对象(如果它是真正的按值传递)。对于大多数目的(从语言用户的角度来看,您),传递给函数的对象是引用,因为您可以修改该对象并且它会影响调用者的对象。另请参阅fantastic answers to this question

【讨论】:

    【解决方案2】:

    好的,让我解释一下你的代码:

    var x, y;
    x = { 'blah': 'foo' };
    y = x;
    x = { 'bar': 'bas' };
    

    因此,您声明了两个变量,然后将对象值分配给第一个变量:

    x = { 'blah': 'foo' };
    

    那么,这里发生了什么:

    1. 对象字面量 - { ... } - 被评估,从而创建和初始化一个新的本地对象。
    2. 对该对象的引用分配给变量x

    接下来,这一行

    y = x;
    

    仅将存储在x 中的引用复制 到变量y。现在两个变量都存储了对对象的相同引用。

    最后是这一行

    x = { 'bar': 'bas' };
    

    为变量x 分配一个新值。评估对象字面量会导致创建/初始化 另一个 对象,并且对该对象的引用存储在 x 中。

    然而,变量y 仍然持有对第一个对象的引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-06
      • 2013-09-13
      • 2021-05-20
      • 2013-01-26
      相关资源
      最近更新 更多