Шаблоны ECMAScript возвращают разные результаты - PullRequest
3 голосов
/ 06 марта 2019

Я изучаю ECMAScript 2016. Я пытался использовать литералы шаблонов для создания простой функции для расчета налога, но я обнаружил, что когда я использую разные стили цикла, функция просто возвращает мне совершенно разные результаты.

Когда я использую for стиль петли:

const total = 30
function figureTax(literals) {
  let res = ''
  for ( let i = 0; i < literals.length; ++i) {
    res += literals[i]
    if (i < arguments.length) {
      res += arguments[i]
    }
  }
  // let i = 0
  // while (i < literals.length) {
  //   res += literals[i++]
  //   if (i < arguments.length) {
  //     res += arguments[i]
  //   }
  // }
  return res
}
const res = figureTax`Your tax is (${ total * 0.15 } with tax!)`
console.log(res)

Это вернуло меня

Ваш налог составляет (Ваш налог (с налогом!) С налогом!) 4,5

При использовании while стиль:

const total = 30
function figureTax(literals) {
  let res = ''
  // for ( let i = 0; i < literals.length; ++i) {
  //   res += literals[i]
  //   if (i < arguments.length) {
  //     res += arguments[i]
  //   }
  // }
  let i = 0
  while (i < literals.length) {
    res += literals[i++]
    if (i < arguments.length) {
      res += arguments[i]
    }
  }
  return res
}
const res = figureTax`Your tax is (${ total * 0.15 } with tax!)`
console.log(res)

Он вернул мне правильный результат:

Ваш налог (4,5 с налогом!)

Кто-нибудь может это объяснить?

Ответы [ 4 ]

3 голосов
/ 06 марта 2019

Это не имеет ничего общего с циклом for или while. Если вы используете тег функции , то первый аргумент - это массив строковых литералов, а все последующие - это переменные интерполяции. Вы используете arguments, который является всеми аргументами функции. Смотри ниже фрагмент:

const total = 30;

function figureTaxWithFor(literals, ...args) {
  
  let res = '';
  
  for ( let i = 0; i < literals.length; ++i) {
  
    res += literals[i];
  
    if (i < args.length) res += args[i];
  }

  return res;
}

function figureTaxWithWhile(literals, ...args) {
  
  let res = '';
  let i = 0;

  while (i < literals.length) {
    
    res += literals[i++];
  
    if (i - 1 < args.length) res += args[i - 1];
  }

  return res;
}

const res = figureTaxWithFor`Your tax is (${ total * 0.15 } with tax!)`;
const res2 = figureTaxWithWhile`Your tax is (${ total * 0.15 } with tax!)`;
console.log(res);
console.log(res2);
2 голосов
/ 06 марта 2019

Чтобы ответить на ваш вопрос, изменив код как можно меньше, это потому, что ваш цикл while увеличивается до i перед доступом к arguments, но ваш цикл for был , а не . Если переписать цикл for следующим образом, он также будет работать:

const total = 30
function figureTax(literals) {
  let res = ''
  for ( let i = 0; i < literals.length;) {
    res += literals[i++]
    if (i < arguments.length) {
      res += arguments[i]
    }
  }
  return res
}
const res = figureTax`Your tax is (${ total * 0.15 } with tax!)`
console.log(res)
1 голос
/ 06 марта 2019

разница возникает из-за того, что вы увеличиваете i в цикле while:

res += literals[i++]

для вашей первой итерации, это вернет literals[0], но будет сравнивать 1 < arguments.length и добавитьarguments[1].

однако в цикле for вы увеличиваете с помощью ++i:

for ( let i = 0; i < literals.length; ++i) {

для вашей первой итерации, это вернет literals[**1**] и будет сравниваться1 < arguments.length и добавьте arguments[1].

, чтобы исправить цикл for, измените на i++ и добавьте + 1, где необходимо:

const total = 30

function figureTax(literals) {
  let res = ''

  for ( let i = 0; i < literals.length; i++) {
    res += literals[i]

    if ((i + 1) < arguments.length) {
      res += arguments[i + 1]
    }
  }

  return res
}

const res = figureTax`Your tax is (${ total * 0.15 } with tax!)`
console.log(res)
//Your tax is (4.5 with tax!)

для получения дополнительной информации см. В чем разница между ++ i и i ++?

0 голосов
/ 06 марта 2019

Ваша проблема состоит в том, чтобы взять тот же индекс для literals, что и для arguments, и хотя arguments[0] равен literals, вы также получаете такой же контент.

Чтобы преодолеть это, выможет взять синтаксис отдыха

figureTax(literals, ...params)

и перехватить все параметры и цикл с одинаковым индексом.В этом подходе используется проблема последнего параметра.


Почему бы не упростить цикл для проверки литералов и аргументов одинаковой длины.

function figureTax(literals) {
    let res = literals[0];
    for (let i = 1; i < literals.length; ++i) {
        res += arguments[i] + literals[i];
    }
    return res;
}

const total = 30
const res = figureTax`Your tax is (${ total * 0.15 } with tax!)`

console.log(res)
console.log(figureTax``);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...