Что почему!? Хитрый код JS распространяется ... и [] .concat - PullRequest
0 голосов
/ 04 ноября 2018

Просто изучал исходный код Laravel Mix (настройка веб-пакета), чтобы вдохновиться настройкой собственного веб-пакета, когда натолкнулся на это.

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

Я не могу понять, в чем смысл этого, но я верю, что Тейлор не включил бы ничего лишнего только ради этого.

Конечно, что-нибудь из этого так же хорошо?

rules.concat(newRules)

или

rules.push(...newRules)

или даже старый добрый цикл! Но зачем соглашаться на пустой массив, прежде чем распространять элементы?

Очень признателен, если кто-нибудь сможет просветить меня об этом.

1 Ответ

0 голосов
/ 04 ноября 2018

Я могу только строить догадки, поскольку я не создавал код, но я предполагаю, что намерение состоит в том, чтобы добавить newRules к rules, где newRules может быть любого типа (не только массив). concat создаст новый массив, пока мы хотим, чтобы исходный массив был мутирован. push мутирует массив, но как вы справляетесь со случаем, когда newRules является массивом? Вы не можете просто вставить newRules в rules, потому что это будет массив внутри массива, и вы не можете распространять newRules, потому что не все является итеративным. [].concat(newRules) добавит все newRules к массиву, который, по сути, "преобразует" не-массивы в массив, а распространение этого массива внутри 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>
...