什么为什么!?棘手的 JS 代码传播...和 ​​[].concat

What, why!? Tricky JS code spread ... and [].concat

我刚刚浏览了 Laravel Mix(webpack 设置)的源代码,以便在遇到此问题时获得一些关于设置我自己的 webpack 的灵感。

rules.push(...[].concat(newRules))

我不明白这是什么意思,但我相信泰勒不会为了它而包含任何多余的东西。

当然这些都一样好吗?

rules.concat(newRules)

rules.push(...newRules)

甚至是一个很好的旧 for 循环!但是为什么在传播元素之前连接到空数组呢?

如果有人能就此启发我,将不胜感激。

我只能推测,因为我没有编写代码,但我想我的目的是将 newRules 添加到 rules,其中 newRules 可以是任何类型(不仅仅是大批)。 concat will create a new array while we want the original array mutated. push 改变了数组,但是你如何处理 newRules 是数组的情况?您不能只是将 newRules 推入 rules,因为它将是一个数组中的数组,您不能展开 newRules,因为并非所有内容都是可迭代的。 [].concat(newRules) 会将所有 newRules 添加到一个数组中,该数组本质上是 'converts' 非数组到一个数组中,然后在 push 中传播该数组会将这些项目添加到 rules.

查看下面的测试用例并单击 运行 片段 以查看实际效果:

const PASSED = '✅ PASSED';
const FAILED = '❌ FAILED';

(() => {
  console.log('`rules.concat(newRules)`');
  (() => {
    const expectation = [1, 2, 3, 4, 5, 6];
    const rules = [1, 2, 3];
    const newRules = [4, 5, 6];
    rules.concat(newRules);
    console.log('where `newRules` is an array:', _.isEqual(expectation, rules) ? PASSED : FAILED);
  })();

  (() => {
    const expectation = [1, 2, 3, 4];
    const rules = [1, 2, 3];
    const newRules = 4;
    rules.concat(newRules);
    console.log('where `newRules` is not an array:', _.isEqual(expectation, rules) ? PASSED : FAILED);
  })();
  console.log('');
})();

(() => {
  console.log('');
  console.log('`rules.push(newRules)`');
  (() => {
    const expectation = [1, 2, 3, 4, 5, 6];
    const rules = [1, 2, 3];
    const newRules = [4, 5, 6];
    rules.push(newRules);
    console.log('where `newRules` is an array:', _.isEqual(expectation, rules) ? PASSED : FAILED);
  })();

  (() => {
    const expectation = [1, 2, 3, 4];
    const rules = [1, 2, 3];
    const newRules = 4;
    rules.push(newRules);
    console.log('where `newRules` is not an array:', _.isEqual(expectation, rules) ? PASSED : FAILED);
  })();
  console.log('');
})();

(() => {
  console.log('');
  console.log('`rules.push(...[].concat(newRules))`');
  (() => {
    const expectation = [1, 2, 3, 4, 5, 6];
    const rules = [1, 2, 3];
    const newRules = [4, 5, 6];
    rules.push(...[].concat(newRules));
    console.log('where `newRules` is an array:', _.isEqual(expectation, rules) ? PASSED : FAILED);
  })();

  (() => {
    const expectation = [1, 2, 3, 4];
    const rules = [1, 2, 3];
    const newRules = 4;
    rules.push(...[].concat(newRules));
    console.log('where `newRules` is not an array:', _.isEqual(expectation, rules) ? PASSED : FAILED);
  })();
})();
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>