繁体   English   中英

Array.push() 和 Spread 语法之间的区别

[英]Difference between Array.push() and Spread syntax

算法问题陈述:找到与目标总和相加的最小数组。

代码问题:我不明白结果的差异:

  • 使用 arr.push() 方法

对比

  • 使用传播语法

请参考下面的评论行。

Spread 语法返回正确的解决方案,而 .push() 方法继续推入同一个数组。 我不明白为什么它一直在 memory 中引用相同的数组。

提前谢谢了!

let howSum = (target, arr, memo = {}) => {
    if (target in memo) return memo[target];
    if (target === 0) return [];
    if (target < 0) return null;

    let smallest = null;

    for (let e of arr) {
        if (howSum(target - e, arr, memo) !== null) {
            let result = howSum(target - e, arr, memo);
            // result.push(e);
            result = [...result, e];

            if (smallest === null || result.length < smallest.length) {
                smallest = result;
            }
        }
    }

    memo[target] = smallest;
    return smallest;
};

console.log(howSum(10, [1, 2, 5])); // [5, 5]

array.push(element)array = [...array, element]

Array.push在现有数组的末尾添加一个元素,而扩展语法创建一个全新的数组。 例如,下面的代码会抛出一个错误,因为我们试图重新定义一个const

const array = ["foo", "bar"];
array = [...array, "baz"]; // Uncaught TypeError: invalid assignment to const 'array'

Array.push添加到现有数组,因此无需重新定义:

const array = ["foo", "bar"];
array.push("baz"); // No error; "baz" is successfully added to the end of the array.

另一个区别是速度。 array.push(element)array = [...array, element];快约 2,500 倍


正如@FelixKling 所指出的,扩展语法本身不会创建新数组。 您还可以在 function 中使用扩展语法,如下所示: myFunction(...myArray) 这将使用数组元素作为 arguments。 所以换句话说, ...myArray不会创建一个新数组,但[...myArray]会。 只是一个值得注意的小细节。


为什么你的循环一直引用 memory 中的相同数组

Spread 语法返回正确的解决方案,而 .push() 方法继续推入同一个数组。 我不明白为什么它一直在 memory 中引用相同的数组。

JavaScript(JavaScript arrays 是对象)中的对象是引用类型,而不是值类型。 因此,使用扩展语法,您创建了一个数组 ( result ),但仍将旧数组 ( arr ) 提供给您的 function。 当您使用Array.push时,您修改了提供给 function 的数组。 并且由于您修改了提供的数组(而不是创建本地数组),您将继续使用数组中的新值调用 function。 当您使用扩展语法时,您创建了一个新数组(因此result不引用arr数组),并且当您使用arr参数调用 function 时,您仍然具有与第一次调用 function 时相同的值。

@trincot 对您的代码中发生的事情进行了简洁的分解

这是您可以在 JavaScript 控制台中进行的实验:

const myArray = ["foo", "bar"];

function changeArray(arrayParameter) {
  const arrayVariable = arrayParameter;
  // We are still referencing the array that was supplied to our function, so
  // although it looks like we tried to duplicate the array, arrayVariable.push,
  // arrayParameter.push, and myArray.push will all modify the same array.
  arrayVariable.push("baz");
}

changeArray();
console.log(myArray); // ["foo", "bar", "baz"]

.push()方法继续推送到同一个数组上。 我不明白为什么它一直在 memory 中引用相同的数组。

如果我们采用您不使用扩展语法而是push的代码变体,那么请意识到:

  • push改变数组,它不会创建一个新数组
  • 您的代码创建新数组的唯一位置是return []

所以,看看return []之后会发生什么:

  • result.push(e); 将该数组更改为[e]
  • 第一次smallest的是 null,因此smallest成为对该单个数组的引用。
  • memo[target]处对单个数组进行了另一个引用
  • 此引用返回给调用者,调用者将其分配给result
  • 一个新值被推送到该单个数组中,该数组现在有两个元素。 它来了:
  • 由于上面提到的memo[target]引用了与result相同的数组,你实际上已经改变了memo[target]memo[target].length现在将是 2。

这是不希望的。 一旦将数组分配给memo ,它就永远不会发生变异。 这就是为什么在您的代码中的某个时刻您应该创建一个新数组的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM