为什么这个函数会改变数据?

Why does this function mutate data?

function bubbleSort(toSort) {
  let sort = toSort;
  let swapped = true;
  while(swapped) {
    swapped = false;
    for(let i = 0; i < sort.length; i++) {
      if(sort[i-1] > sort[i]) {
        let temp = sort[i-1];
        sort[i-1] = sort[i];
        sort[i] = temp;
        swapped = true;
      }
    }
  }
  return sort;
}

let asdf = [1,4,3,2];
let asd = bubbleSort(asdf);

console.log(asdf, asd);

此代码的输出是:[ 1, 2, 3, 4 ] [ 1, 2, 3, 4 ]。

我的预期: [ 1, 4, 3, 2 ] [ 1, 2, 3, 4 ].

我想知道的是,为什么这会改变 asdf 变量? bubbleSort 函数获取给定数组 (asdf),复制它(排序),然后处理该变量和 returns 它,asd 设置为等于。我觉得自己像个白痴,但我不知道为什么会这样:(

The bubbleSort function takes the given array (asdf), makes a copy of it (sort)

不,不是。赋值不会复制一个对象,它会创建另一个对现有对象的引用。

复制数组的一种简单方法是使用 Array.prototype.slice:

  let sort = toSort.slice( 0 );

有关复制对象的更多信息,请参阅:How do I correctly clone a JavaScript object?

您正在对作为可变函数参数给出的输入列表进行排序。当您将列表分配给一个新变量时,它不会创建 'copy' 它只是创建另一个指向相同列表、相同数据的引用,然后您可以对其进行排序。这就是asdf和add变量相同的原因,因为它们是两个变量,指向相同的内存位置,相同的数据。

如果您希望复制数组而不是修改输入数组,请查看 javascript slice() 方法。

您需要克隆原始数组以避免原始数组发生变化。克隆可以通过使用

来完成
  1. slice()原型方法。
  2. 循环.
  3. Array.from().
  4. concat().

let sort = toSort;替换为let sort = toSort.slice(0);

 let sort=[];
  for(var i=0;i < toSort.length;i++){
  sort[i]=toSort[i];  
  }

  let sort = Array.from(toSort);

let sort = toSort.concat();

function bubbleSort(toSort) {
  let sort = toSort.slice(0);
  let swapped = true;
  while (swapped) {
    swapped = false;
    for (let i = 0; i < sort.length; i++) {
      if (sort[i - 1] > sort[i]) {
        let temp = sort[i - 1];
        sort[i - 1] = sort[i];
        sort[i] = temp;
        swapped = true;
      }
    }
  }
  return sort;
}

let asdf = [1, 4, 3, 2];

let asd = bubbleSort(asdf);

console.log(asdf, asd);