代码之家  ›  专栏  ›  技术社区  ›  bellotas

基本javascript-变量[重复]

  •  0
  • bellotas  · 技术社区  · 6 年前

    我有一段代码,它没有按我的预期工作。我创建了一个数组,并将其复制到一个新数组中。我原以为第二个在第一个做的时候不会改变它的值,但看起来它做了。我怎么能避免呢?我想在按“重置”后打印初始值,但当arrayStringDates2的值更改时,aux的值已更改。

    var arrayStringDates2 = ["10/01/2017", "20/01/2018", "16/12/2015"];
    var aux = arrayStringDates2;
    document.getElementById("arrayStringDates2").innerHTML = arrayStringDates2;
    
    document.addEventListener('click', function(event) {
      if (event.target.id == "format2") {
        for (i = 0; i < arrayStringDates2.length; i++) {
          arrayStringDates2[i] = arrayStringDates2[i].replace(/["/"]/gi, "");
        }
        document.getElementById("arrayStringDates2").innerHTML = arrayStringDates2;
      }
      if (event.target.id == "resetFormat") {
        console.log(aux)
        document.getElementById("arrayStringDates2").innerHTML = aux;
      }
    }, false);
    <button id="format2">
    		Format
    	</button>
    <button id="resetFormat">
    		Reset
    	</button>
    <div id="arrayStringDates2"></div>
    5 回复  |  直到 6 年前
        1
  •  3
  •   Arup Rakshit    6 年前

    aux 具有相同的指针引用,可以使用 slice 方法。

    var arrayStringDates2 = ["10/01/2017", "20/01/2018", "16/12/2015"];
    var aux = arrayStringDates2.slice()
    
        2
  •  0
  •   Sebastian Speitel    6 年前

    复制数组最简单的方法之一是 .slice() .

    但这只会创建数组的副本,而不是内部的非基元值的副本,因此字符串或数字将被复制,而数组的两个副本中的对象将是相同的。

    像这样使用它:

    var arrayStringDates2 = ["10/01/2017", "20/01/2018", "16/12/2015"];
    var aux = arrayStringDates2.slice()
    
        3
  •  0
  •   phuzi    6 年前

    不是你想的那样。。。

    var arrayStringDates2 = ["10/01/2017", "20/01/2018", "16/12/2015"];
    var aux = arrayStringDates2;
    

    不创建数组的副本,只创建对同一数组的两个引用- arrayStringDates2 aux 两者都指向 ["10/01/2017", "20/01/2018", "16/12/2015"]

    您需要做的是创建一个具有相同内容的新数组。因此,更改一个值只会在数组中更改它。

    Array.prototype.slice 是你想要的。

    var arrayStringDates2 = ["10/01/2017", "20/01/2018", "16/12/2015"];
    var aux = arrayStringDates2.slice(); // shallow copy each item in arrayStringDates2 in to a new array
    
    document.getElementById("arrayStringDates2").innerHTML = arrayStringDates2;
    
    document.addEventListener('click', function(event) {
      if (event.target.id == "format2") {
        for (i = 0; i < arrayStringDates2.length; i++) {
          arrayStringDates2[i] = arrayStringDates2[i].replace(/["/"]/gi, "");
        }
        document.getElementById("arrayStringDates2").innerHTML = arrayStringDates2;
      }
      if (event.target.id == "resetFormat") {
        console.log(aux)
        document.getElementById("arrayStringDates2").innerHTML = aux;
      }
    }, false);
    <button id="format2">
    		Format
    	</button>
    <button id="resetFormat">
    		Reset
    	</button>
    <div id="arrayStringDates2"></div>
        4
  •  0
  •   Sven van de Scheur    6 年前

    我有一段代码,它没有按我的预期工作。我创建了一个数组,并将其复制到一个新数组中。我原以为第二个在第一个做的时候不会改变它的值,但看起来它做了。

    这是因为JavaScript处理内存的方式。

    对于基本类型(boolean、null、undefined、number、string、symbol),如果将包含这些类型之一的变量分配给新变量,JavaScript将传递变量的值(按值传递)。值将被复制。

    对于复杂的对象(数组是),Javascript将引用传递到内存中的值(按引用传递)。实际值可以由多个引用指向,并且在技术上是共享的。如果将包含对象类型的变量分配给新变量,则只复制对内存中该位置的引用。

    JavaScript这样做是为了提高内存效率,但它会导致您描述的行为。如果更改对象,则指向该对象的所有变量都将看到相同的效果。

    我怎么能避免呢?

    你不想做的是克隆这个对象,让它在内存中有自己的位置。根据您的用例,有很多克隆方法。

    internet上到处都是描述用例和解决方案的文章,例如,请参见: https://davidwalsh.name/javascript-clone-array

        5
  •  0
  •   onejeet    6 年前

    对于blink browsers,slice是复制数组的最快方法。 但是对于非闪烁浏览器,您可以使用while循环或in循环。

    使用切片方法:

    var newArray = myArray.slice();

    另外,在ES6中复制数组的最简单方法之一是使用数组扩展。

    var newArray = [...myArray];

    **这些方法正在复制数组,但如果数组由对象组成,则它们仍被引用,并将随着原始对象的更改而更改。