【问题标题】:What, why!? Tricky JS code spread ... and [].concat什么为什么!?棘手的 JS 代码传播...和 ​​[].concat
【发布时间】:2019-04-08 00:27:28
【问题描述】:

当时我正在浏览 Laravel Mix(webpack 设置)的源代码以获取设置我自己的 webpack 的一些灵感。

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

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

这些肯定都一样好吗?

rules.concat(newRules)

rules.push(...newRules)

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

如果有人能在这方面启发我,不胜感激。

【问题讨论】:

  • 似乎他们想使用Symbol.isConcatSpreadable behaviour,而不仅仅是迭代协议。
  • 也许rules.push(...Array.from(newRules)) 更容易理解。或rules = rules.concat(newRules);

标签: javascript ecmascript-6 laravel-mix


【解决方案1】:

我只能推测,因为我没有编写代码,但我想目的是将newRules 添加到rules,其中newRules 可以是任何类型(不仅仅是数组)。 concat 将创建一个新数组,而我们希望原始数组发生突变。 push 改变了数组,但是你如何处理newRules 是一个数组的情况?您不能将newRules 推入rules,因为它将是数组中的一个数组,并且您不能传播newRules,因为并非所有内容都是可迭代的。 [].concat(newRules) 会将所有 newRules 添加到一个数组中,该数组本质上是将非数组“转换”为一个数组,并在 push 中传播该数组会将这些项目添加到 rules

查看下面的测试用例,然后单击 Run sn-p 来查看它的实际效果:

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>

【讨论】:

  • 就是这样!!非常感谢您将其分解并提供详细示例。我仍然不明白[].concat(newRules) 将如何将newRules 转换为数组(因为 concat 也适用于普通的单个元素),但是改变原始数组并且仍然能够接受数组是有意义的!
  • 如果你连接两个数组,你会得到一个数组,两个数组连接在一起。如果你将一个非数组与一个数组连接起来,你将得到一个数组,其中非数组添加到末尾。请参阅这两个都产生[1, 2, 3] 的示例:[1, 2].concat(3)[1, 2].concat([3])
猜你喜欢
  • 1970-01-01
  • 2011-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多