Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将对象属性保存到阵列时出现奇怪的重复_Javascript_Arrays_Javascript Objects - Fatal编程技术网

Javascript 将对象属性保存到阵列时出现奇怪的重复

Javascript 将对象属性保存到阵列时出现奇怪的重复,javascript,arrays,javascript-objects,Javascript,Arrays,Javascript Objects,我想循环一个对象,对它的每个属性执行一些更改,然后将它们推送到一个数组中。每个对象属性都被推送多次(在JSFIDLE中,为了简单起见,我将其设置为推送两次)。每个“迭代”都有一些不同的属性(JSFIDLE只显示1,即“数字”) 但是,似乎在单个循环中推送的所有对象都不能具有唯一的属性。我正在寻找解决办法 对不起,我的英语很差,很难解释这个问题,而且更容易看到JSFIDLE 实际产量: [{ x: 1, number: 1 }, { x: 1, number: 1 }, { y: 2, n

我想循环一个对象,对它的每个属性执行一些更改,然后将它们推送到一个数组中。每个对象属性都被推送多次(在JSFIDLE中,为了简单起见,我将其设置为推送两次)。每个“迭代”都有一些不同的属性(JSFIDLE只显示1,即“数字”)

但是,似乎在单个循环中推送的所有对象都不能具有唯一的属性。我正在寻找解决办法

对不起,我的英语很差,很难解释这个问题,而且更容易看到JSFIDLE

实际产量:

[{ x: 1, number: 1 },  
{ x: 1, number: 1 },  
{ y: 2, number: 1 },  
{ y: 2, number: 1 },  
{ z: 3, number: 1 },  
{ z: 3, number: 1 }] 
预期产出:

[{ x: 1, number: 0 },
{ x: 1, number: 1 },
{ y: 2, number: 0 },
{ y: 2, number: 1 },
{ z: 3, number: 0 },
{ z: 3, number: 1 }]
代码:

var items={
“a”:{
“x”:1
},
“b”:{
“y”:2
},
“c”:{
“z”:3
}
};
var=[];
对于(var输入项){
var项目=项目[关键];
if(items.hasOwnProperty(键)){
对于(变量i=0;i<2;i++){
项目编号=i;
推(物品);
}
}
}
console.log(某物);

我将通过干运行来解释。在下面的循环中,我们选择“items”对象中的第一个键“a”。现在让我们进入循环

    for ( var key in items ) {

      //key has been set to "a"

     var item = items[key]; 

     //item now "refers" to the object items["a"] which is {"x":1}

      if ( items.hasOwnProperty(key) ) {
        for ( var i = 0; i < 2; i++ ) {

          //in loop 1 item is referring to {"x":1}
          //in loop 2 item is referring to {"x":1,"number":0} (modified in first iteration)

          item.number = i;

         //in loop 1 item gets "number" property and object becomes {"x":1,"number":0} in memory
         //in loop 2 it will still modify the same object. Hence {"x":1,"number":0} becomes {"x":1,"number":1}


          something.push(item);
          //in loop1 reference to the object gets pushed.
          //in loop2 reference to the object gets pushed. 
          //both references (items) essentially point to same object.

        }
      }
    }
for(变量输入项){
//密钥已设置为“a”
var项目=项目[关键];
//item now“指的是对象项[“a”],即{“x”:1}
if(items.hasOwnProperty(键)){
对于(变量i=0;i<2;i++){
//在循环1中,项是指{“x”:1}
//在循环2中,项引用了{“x”:1,“number”:0}(在第一次迭代中修改)
项目编号=i;
//在循环1中,项获取“number”属性,对象在内存中变为{“x”:1,“number”:0}
//在循环2中,它仍然会修改相同的对象,因此{“x”:1,“number”:0}变成了{“x”:1,“number”:1}
推(物品);
//在loop1中,对对象的引用被推送。
//在loop2中,对对象的引用被推送。
//两个引用(项)基本上指向同一个对象。
}
}
}
要获得预期的输出,您需要创建对象的副本,而不是多个引用。在Javascript中,对象的克隆不是直接的。你可以参考这个链接

但是,当前代码的一个简单解决方案是创建克隆函数并使用它,而不必担心深度克隆问题和原型继承属性。这是修改后的代码

function clone(obj) {
    if (null == obj || "object" != typeof obj) return obj;
    var copy = obj.constructor();
    for (var attr in obj) {
        if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
    }
    return copy;
}
var items = {
  "a": {
    "x": 1
  },
  "b": {
    "y": 2
  },
  "c": {
    "z" : 3
  }
};



var something = [];

for ( var key in items ) {
  var item = items[key];

  if ( items.hasOwnProperty(key) ) {
    for ( var i = 0; i < 2; i++ ) {
      var tempItem = clone(item);
      tempItem.number = i;
      something.push(tempItem);
    }
  }
}

console.log(something);
功能克隆(obj){
如果(null==obj | |“object”!=typeof obj)返回obj;
var copy=obj.constructor();
for(obj中的var attr){
如果(obj.hasOwnProperty(attr))copy[attr]=obj[attr];
}
返回副本;
}
可变项目={
“a”:{
“x”:1
},
“b”:{
“y”:2
},
“c”:{
“z”:3
}
};
var=[];
对于(var输入项){
var项目=项目[关键];
if(items.hasOwnProperty(键)){
对于(变量i=0;i<2;i++){
var tempItem=克隆(项目);
tempItem.number=i;
推(临时项目);
}
}
}
console.log(某物);

如果您觉得有用,请向上投票。

您正在推送
项作为参考。第0个和第1个元素相同(第2个和第3个,第4个和第5个)。您可以复制它们,但这会取消引用该项。我不知道你需要哪种解决方案。这取决于您想对
某物执行什么操作
。取消引用该项不会有问题,我需要的是克隆,而不是数组中的确切项。我该怎么办?我没听说过JS vefore中的引用,你有一些文献的链接吗?多谢各位@Halcyon阅读参考资料。似乎JS只在处理对象时使用引用,这很奇怪。如果取消引用不是问题,如何复制对象?谢谢在JavaScript中,克隆/复制并不简单,有些对象无法克隆。但是,如果您的目标对象只是数据(在您的例子中就是这样),那么它就相当简单。您可以这样做:
var clone=JSON.parse(JSON.stringify(item);
@Halcyon-Clever,它很好用。非常感谢!
function clone(obj) {
    if (null == obj || "object" != typeof obj) return obj;
    var copy = obj.constructor();
    for (var attr in obj) {
        if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
    }
    return copy;
}
var items = {
  "a": {
    "x": 1
  },
  "b": {
    "y": 2
  },
  "c": {
    "z" : 3
  }
};



var something = [];

for ( var key in items ) {
  var item = items[key];

  if ( items.hasOwnProperty(key) ) {
    for ( var i = 0; i < 2; i++ ) {
      var tempItem = clone(item);
      tempItem.number = i;
      something.push(tempItem);
    }
  }
}

console.log(something);