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

Pmc*_*rea 6 javascript arrays algorithm dynamic-programming ecmascript-6

算法问题陈述:找到加起来等于目标总和的最小数组。

代码问题: 我不明白以下情况下结果的差异:

  • 使用 arr.push() 方法

  • 使用扩展语法

请参考下面的评论行。

Spread 语法返回正确的解决方案,而 .push() 方法继续推送到同一个数组。我不明白为什么它不断引用内存中的同一数组。

提前谢谢了!

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]
Run Code Online (Sandbox Code Playgroud)

Sam*_*ert 11

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

\n

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

\n
const array = ["foo", "bar"];\narray = [...array, "baz"]; // Uncaught TypeError: invalid assignment to const \'array\'\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
const array = ["foo", "bar"];\narray.push("baz"); // No error; "baz" is successfully added to the end of the array.\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
\n

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

\n
\n

为什么你的循环不断引用内存中的同一个数组

\n
\n

Spread 语法返回正确的解决方案,而 .push() 方法继续推送到同一个数组。我不明白为什么它不断引用内存中的同一数组。

\n
\n

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

\n

@trincot 写了一个简洁的分解对代码中发生的情况

\n

您可以在 JavaScript 控制台中进行以下实验:

\n
const myArray = ["foo", "bar"];\n\nfunction changeArray(arrayParameter) {\n  const arrayVariable = arrayParameter;\n  // We are still referencing the array that was supplied to our function, so\n  // although it looks like we tried to duplicate the array, arrayVariable.push,\n  // arrayParameter.push, and myArray.push will all modify the same array.\n  arrayVariable.push("baz");\n}\n\nchangeArray();\nconsole.log(myArray); // ["foo", "bar", "baz"]\n
Run Code Online (Sandbox Code Playgroud)\n