推送的奇怪行为
Strange behaviour of the 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
在此处查看脚本:
当您将对象推送到数组时,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);
}
在JavaScript中,克隆对象并不像听起来那么容易。对象是引用类型而不是值类型。数字或字符串等值类型将被复制,对象将通过引用传递,这意味着您的变量只是指向存储对象的内存区域的指针。
将此变量赋值给另一个变量会创建一个指向指针的指针,依此类推。
如果您使用“===”运算符比较对象变量,如果两个变量都指向同一个对象,它将 return 'true' 如果它们代表不同的实例,它将 'false' .请注意,即使对象具有完全相同的属性集,结果也将是 'false'。比较的是参考。
在您的示例中,push(o) 不会复制对象 - 它会添加指针变量。以下代码将 return '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
这是我无法理解的简单脚本:
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
在此处查看脚本:
当您将对象推送到数组时,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);
}
在JavaScript中,克隆对象并不像听起来那么容易。对象是引用类型而不是值类型。数字或字符串等值类型将被复制,对象将通过引用传递,这意味着您的变量只是指向存储对象的内存区域的指针。
将此变量赋值给另一个变量会创建一个指向指针的指针,依此类推。
如果您使用“===”运算符比较对象变量,如果两个变量都指向同一个对象,它将 return 'true' 如果它们代表不同的实例,它将 'false' .请注意,即使对象具有完全相同的属性集,结果也将是 'false'。比较的是参考。
在您的示例中,push(o) 不会复制对象 - 它会添加指针变量。以下代码将 return '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