将一个对象推入数组,对象覆盖前一个

Posted

技术标签:

【中文标题】将一个对象推入数组,对象覆盖前一个【英文标题】:Push an object to array, obejct overwritting the previos one 【发布时间】:2018-01-20 08:21:21 【问题描述】:

我正在尝试将对象 resultOBJ 推送到数组 resultArray 单击“Добавить обозначение”按钮时。 第一个对象已发送好,数据与我要查找的数据相同,但是当我推送另一个对象时,第二个对象正在重写前一个对象,第三个对象正在重写第一个和第二个,依此类推。 这是我的代码。请告诉我我做错了什么。 提前致谢。

var color = red:"#ff0000",purple:"#990099",green:"#33cc33",yellow:"#ffff00",blue:"#0000ff",orange:"#ff8000",pink:"#ff0080",
          skyblue:"#00ffff",black:"#000000",gray:"#808080",brown:"#4d1f00";

      var diams = ["60","65","68","69","70","75","76","80","81","82","85","90"];

      //show hidden elements
      $(document).ready(function()
          $("#addRowDDL").click(function()
              $("#DDL,#deleteRowDDl,#useIt").fadeIn("slow");
          );
      );

        var resultOBJ=new Object();            
        var resultArray = new Array();
        var finalobj =  ;  
        var obj = new Object();            
      function addDropDownLists()
          
          var myObject = $("#htmltoget").children().clone();
          $("#DDL").append(myObject);

          $.each(diams,function(key,value)
              myObject.find(".chooseDiams").append($("<option></option>").attr("value",key)
                .text(value));
          );

          $.each(color,function(key,value)
              myObject.find(".chooseColor").append($("<option></option>").attr("value",key)
                .text(key));
          );

          myObject.find(".chooseColor").change(function()

              displayColors(this);
          );
          myObject.find(".chooseDiams").change(function()
              displayDiams(this);
              
          );  

              resultArray.push(obj);

      //End of addDropDownLists function
 function displayColors(param)
          var colorValues = $(param).val();
          resultOBJ.color=colorValues;
          
      
 function displayDiams(param)
        var  diamsValues = $(param).val() || [];
        resultOBJ.diams=diamsValues;
      
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
<div id="htmltoget" style="display: none;">
<div class="DDL-Con">
    <div class="diams">
        <p>Диаметр</p>
        <select class="chooseDiams" multiple>
          <option selected hidden> Выбрать Диаметр</option>
        </select>        
    </div>
    <div class="color">
        <p>Цвет</p>
        <select class="chooseColor">
          <option selected hidden>Выбрать Цвет</option>
        </select>
    </div>
</div>
</div>

<button type="button" id="addRowDDL" onclick="addDropDownLists()" style="margin-bottom: 20px;">Добавить обозначение</button>
 <div id="bigwrapper">
  <div id="DDL">        
  </div>      
  </div>
</body>

【问题讨论】:

某些代码似乎被截断了,因为 SO 认为它是帖子中的 html 标记。只有点击编辑才能看到。 您应该在每次调用 addDropDownLists 时创建一个新对象,而不仅仅是在全局范围内创建一次,否则您将重用和覆盖原始对象的属性。 【参考方案1】:

很难说出您要完成的工作,但您推送了obj,它是空的,应该给您一个空对象数组。

此外,您需要为每次调用 addDropDownLists() 创建一个新对象,否则您只是传递了一个引用,更改将影响数组中的每个对象。

//show hidden elements
$(document).ready(function()
      $("#addRowDDL").click(function()
          $("#DDL,#deleteRowDDl,#useIt").fadeIn("slow");
          addDropDownLists();
      );
);

var resultArray = new Array();

  function addDropDownLists()
      var resultOBJ=new Object(); 

      var myObject = $("#htmltoget").children().clone();
      $("#DDL").append(myObject);

      $.each(diams,function(key,value)
          myObject.find(".chooseDiams").append($("<option></option>").attr("value",key)
            .text(value));
      );

      $.each(color,function(key,value)
          myObject.find(".chooseColor").append($("<option></option>").attr("value",key)
            .text(key));
      );

      myObject.find(".chooseColor").change(function()
          resultOBJ.color = $(this).val();
      );
      myObject.find(".chooseDiams").change(function()
          resultOBJ.diams = $(this).val() || [];     
      );  

          resultArray.push(resultOBJ);
                        console.log(JSON.stringify(resultArray));
  //End of addDropDownLists function

此设置会在第一次单击按钮时将一个空对象插入到数组中,或者如果没有更改。不确定您要完成什么,所以我保持原样。

演示:https://jsfiddle.net/3p37znq1/2/

【讨论】:

它有效。万分感谢。如果您知道如何删除我推入数组的最后一个对象,我打算使用 resultArray.pop(resultOBJ);有更好的建议吗?谢谢! 您的意思是要删除开头的那个空对象还是实际删除添加到resultArray 的最后一个对象? 最后一个添加到 resultArray 的对象,因为开头的空对象被函数覆盖了所需的值。【参考方案2】:

你不推resultOBJ,你推obj,因为你在初始化后不做任何事情,所以它总是空的。

当您每次推送obj 时,您只需推送对同一实例的引用,而不是创建新实例。对obj 的任何更改都会影响resultArray 中的所有项目。

在更改处理程序中,您始终会更新 resultOBJ 的同一实例,并且此更新始终会覆盖先前的更改。实际上,这个对象中的值表示“任何地方最后选择的颜色”和“任何地方最后选择的直径”。

这样的事情应该可以工作:

var resultArray = [];
function renderOption(value, name) 
    var option = document.createElement("option");
    option.value = value;
    option.innerHTML = undefined === name ? value : name;
    return option;


function updateResult(index) 
    var item = resultArray[index], 
        node = document.querySelector("#DDL").childNodes.item(index);
    item.diam = node.querySelector(".chooseDiams").value;
    item.color = node.querySelector(".chooseColor").value;


function addDropDownLists() 

    var container = document.querySelector("#DDL"),
        index = resultArray.length,
        changeHandler = updateResult.bind(null, index),
        tpl = document.querySelector(".DDL-Con"),
        node = tpl.cloneNode(true),
        list, key, len
    ;

    list = node.querySelector(".chooseDiams");
    for (key = 0, len = diams.length; key < len; key++) 
        list.appendChild(renderOption(diams[key]));
    
    list.onchange = changeHandler;

    list = node.querySelector(".chooseColor");
    for (key in color) 
        list.appendChild(renderOption(key, color[key]));
    
    list.onchange = changeHandler;

    container.appendChild(node);
    resultArray.push(
        diam: null,
        color: null
    );
    updateResult(index);

PS:抱歉,我看到你使用 jQuery...我懒得记起它的 API。好久没用了。希望你能抓住主要思想。

PPS:如果你打算删除项目,也许最好绑定整个节点并通过isSameNode()方法搜索它的索引。绑定的索引在移除item后会失效,它们会移位。

【讨论】:

以上是关于将一个对象推入数组,对象覆盖前一个的主要内容,如果未能解决你的问题,请参考以下文章

Javascript将对象推入数组

JS——数组中push对象,覆盖问题,每次都创建一个新的对象

将对象添加到数组而不覆盖

将对象推入数组

如何将对象推入数组?

我在创建一个Class Album后声明了一个对象数组。最后一个对象的变量会覆盖其他对象