使对象不通过引用传递

Posted

技术标签:

【中文标题】使对象不通过引用传递【英文标题】:Make object not pass by reference 【发布时间】:2011-03-18 02:11:01 【问题描述】:

我刚刚发现了在 javascript 中通过引用传递对象的困难方式,例如:

for(var layer = 0; layer < hudLayers['layers'].length; layer++)

    // Store the to-be-calculated values in this object
    var tempValues = hudLayers['layers'][layer];

    tempValues['name'] = 'test';

这将改变 tempValues 和 hudLayers 中的值。 (看起来有点明显,但没有一点代码的帖子看起来很赤裸裸。)

有没有快速的解决方法?

【问题讨论】:

您想为tempValues 分配一个值,但它没有反映在hudLayers 中吗?你为什么想要那个? 你真的想知道吗? :) hudLayers 包含图像宽度和高度的几个变量。这是一个HUD,所以它必须每秒绘制多次。 hudLayers 中的内容实际上是“蓝图”(此图像的宽度基于该变量的值,...)如果我简单地将其写回 hudLayers,则蓝图消失了,屏幕上的图像将始终保持不变。 【参考方案1】:

这不是通过引用传递的示例(您没有传递任何参数)。 但是,您是对的;分配对象不会进行深拷贝。

您可以像这样对对象进行深层复制:

function deepCopy(obj) 
    if (typeof obj !== "object") return obj;
    if (obj.constructor === RegExp) return obj;

    var retVal = new obj.constructor();
    for (var key in obj) 
        if (!obj.hasOwnProperty(key)) continue;
        retVal[key] = deepCopy(obj[key]);
    
    return retVal;

请注意,如果对象的构造函数有任何副作用,此代码将触发它们。

【讨论】:

【参考方案2】:

JavaScript 中没有引用传递。对象是通过引用访问的,这些引用是通过值来分配或传递的,就像在 Java 中一样

【讨论】:

【参考方案3】:

制作对象的深层副本就像objCopy = obj.toSource(); 一样简单。

.toSource on MDN

【讨论】:

我认为toSource 返回一个字符串表示。可以设置一个测试用例吗?

以上是关于使对象不通过引用传递的主要内容,如果未能解决你的问题,请参考以下文章

提升线程不填充通过引用传递的本地对象

通过引用递归传递对象? JAVA

对象引用的变量重新分配使其他对象保持不变(无“传递”分配)

python中的值传递和引用传递(可变对象与不可变对象)也就是赋值的原理-python全部是引用传递

通过引用传递向量使迭代算法以不同的方式运行

python 引用