【问题标题】:How do I pass the value instead of the reference of an array?如何传递值而不是数组的引用?
【发布时间】:2012-02-08 09:22:37
【问题描述】:

我有这个结构:

var a = [];
a.push({"level": 1, "column": 4, "parent": "none", "title": "Node 0", "content": "Parintele suprem", "show": "1"});
var b = a;

a.push({"level": 1, "column": 5, "parent": "none", "title": "Node 1", "content": "Parintele suprem", "show": "1"});

console.log(b);

现在的问题是b 的内容与a 完全相同(第二次推送后的内容)。这表明(如果我错了,请纠正我)当我说 b = a 时,我实际上给了 b 与 a 相同的参考,所以无论我在 a 中做什么,我在 b 中都有。问题是我需要传递价值。所以我有a 的预览,b 的值。

编辑以使问题更清楚:如何传递值而不是引用?

【问题讨论】:

  • “问题是我需要传递值。所以我在 b 中有预览值。”。或者把它拼写成一个问题:“我如何传递值而不是引用?”。

标签: javascript object


【解决方案1】:

我认为您可以使用它来复制值而不是引用:

var b = a.slice(0);  

编辑
正如 cmets 所提到的,这里也提到了:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/slice

slice 不会改变原始数组,但会返回一个新的“一层深”副本,其中包含从原始数组中切片的元素的副本。原始数组的元素被复制到新数组中,如下所示:

  • 对于对象引用(而不是实际对象),切片副本 对象引用 到新数组中。原始数组和新数组 引用同一个对象。如果引用的对象发生更改,则更改 对新数组和原始数组都可见。

  • 对于字符串和数字(​​不是字符串和数字对象),切片副本 字符串和数字 到新数组中。更改字符串或 一个数组中的数字不会影响另一个数组。

如果向任一数组添加新元素,则不影响另一个数组。

【讨论】:

  • 像梦一样工作:)。我还不能接受答案,但我会在 7 分钟内接受(当堆栈允许我时)。
  • 好像是这样。完成当前任务后,我将进行快速测试:)。此外,由于有超过 1 个有效答案,我会发帖回答女巫会更快......从我的快速测试来看,这似乎是切片。但由于我没有合乎逻辑的解释,我无法确定。
  • @zozo。请注意,它仅适用于数组,不适用于对象。看我的回答。
  • 正确...但是我不能使用原型,除非克隆更快,否则我没有任何用途来制作克隆功能,因为切片适合我当前的需求。 +1 寿。
  • +1 请注意,slice 的行为如果你给它 no 参数 is not defined in the spec,因此 var b = a.slice(); 依赖于未指定的、未记录的行为。为避免依赖它,只需传递 0: var b = a.slice(0);
【解决方案2】:

你可以实现一个 clone 方法如下:

function clone(source) {
    var result = source, i, len;
    if (!source
        || source instanceof Number
        || source instanceof String
        || source instanceof Boolean) {
        return result;
    } else if (Object.prototype.toString.call(source).slice(8,-1) === 'Array') {
        result = [];
        var resultLen = 0;
        for (i = 0, len = source.length; i < len; i++) {
            result[resultLen++] = clone(source[i]);
        }
    } else if (typeof source == 'object') {
        result = {};
        for (i in source) {
            if (source.hasOwnProperty(i)) {
                result[i] = clone(source[i]);
            }
        }
    }
    return result;
};

然后:

var b = clone(a);

如果你确定 a 是数组,只使用 Niklas 的:

var b = a.slice();

ps:我的英语很差:)

【讨论】:

    【解决方案3】:

    是的,这就是引用分配在 javascript 中的工作方式。您想克隆对象以制作副本,不幸的是,这比应有的要复杂得多。 MooTools 之类的框架提供了最简单的解决方案,或者您可以推出自己的 clone 函数。

    【讨论】:

      【解决方案4】:

      我能找到的最简单的方法是创建一个 json 字符串,然后解析数据。

      var assiging_variable = JSON.parse(JSON.stringify(source_array));
      

      如果源数组是多维数组,这也有效,array.slice(0) 方法不适用于多维数组。

      【讨论】:

      • 确实是最简单的。虽然不是最理想的;)。还是+1。 no1 之前提到过这个很有趣:))。
      • 我很遗憾这是唯一对我有用的解决方案......我从数组 A 迭代和过滤,删除和添加对象和属性到数组 B,这是唯一有效的方法为了我 。我来自 Python,我不习惯所有 NodeJS\JavaScript 的独特思维。
      • 让 obj_A = Object.assign({}, obj_B );
      【解决方案5】:

      我通过使用“Object.assign({}, source_object )”找到了一个更好的方法:

      let source_obj  = {val1:"A",val2:"B"};
      let copy_obj = Object.assign({}, source_obj);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-25
        • 1970-01-01
        • 1970-01-01
        • 2017-04-06
        • 2019-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多