推动的奇怪行为

时间:2017-07-08 16:46:05

标签: object google-apps-script push

这是我无法理解的简单脚本:

function test() {
  var o = {"groupName":"A"};
  var a = [];
  var b = [{"name":"1"}, {"name":"2"}];
  for (var i in b) {
    var name = b[i].name;
    o.itemName = name;
    a.push(o);
  }
  Logger.log (a);
}

我希望结果是

[
  {
    "groupName": "A",
    "itemName": {
      "name": "1"
    }
  },
  {
    "groupName": "A",
    "itemName": {
      "name": "2"
    }
  }
]

但事实并非如此。它是

[
  {
    "groupName": "A",
    "itemName": {
      "name": "2"
    }
  },
  {
    "groupName": "A",
    "itemName": {
      "name": "2"
    }
  }
]

我希望结果包含两个迭代的相同groupName,但具有不同的itemName

请参阅此处的脚本:

https://script.google.com/d/1VexsBJWZ1SBnb_4vnN1JA7a9KJkYzJ-hOcXwXvD2wa_GTXvdgt9xVOZb/edit?usp=sharing

2 个答案:

答案 0 :(得分:2)

在JavaScript中,克隆对象并不像听起来那么容易。 Object是引用类型而不是值类型。数字或字符串等值类型将被复制,对象将通过引用传递,这意味着您的变量只是指向存储对象的内存区域的指针。

将此变量分配给另一个变量将创建指向指针的指针,依此类推。

如果使用' ==='来比较对象变量运营商,它将返回真实的'如果两个变量都指向同一个对象并且“假”'如果它们代表不同的实例。请注意,结果将是“假”'即使对象具有完全相同的属性集。被比较的是参考。

在您的示例中,push(o)不会复制对象 - 它将添加指针变量。以下代码将返回' true',因为您存储了两个指向对象的指针而不是两个指针。

Logger.log(a[0] === a[1]); //returns true

以下代码复制对象。

  var array=[];

  for(var j in b) {

  var name = b[j].name;
  var newObj = {};
  newObj.itemName = name;

  for(var prop in o){

  newObj[prop] = o[prop];

  }

  array.push(newObj);


  }

  Logger.log(array);
  Logger.log(array[0] === array[1]); //will return false

答案 1 :(得分:0)

当您将对象推送到数组时,JavaScript(Google Apps脚本)会通过引用来执行此操作,因此下次更改o对象时,它将在a数组中的任何位置更改。

您可以在每次迭代时创建o变量,使其按预期执行:

function test() {
  var a = [];
  var b = [{"name":"1"}, {"name":"2"}];
  for (var i in b) {
    var name = b[i].name;
    var o = {"groupName":"A"};
    o.itemName = name;
    a.push(o);
  }
  Logger.log(a);
}