我正在学习ECMAScript2016。我尝试使用模板文字来构建一个简单的功能来计算税款,但是我发现当我使用不同的循环样式时,该功能返回的结果完全不同。
当我使用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!)
任何人都可以解释吗?
答案 0 :(得分:3)
与for或while循环无关。如果使用tag functions,则第一个参数是字符串文字的数组,所有下一个都是插值变量。您使用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);
答案 1 :(得分:2)
要通过尽可能少地更改代码来回答您的问题,这是因为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)
答案 2 :(得分:1)
区别来自您在while循环中增加i
的位置:
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!)
答案 3 :(得分:0)
您的问题是,literals
的索引与arguments
的索引相同,而arguments[0]
等于literals
时,您也会得到相同的内容。
要克服这个问题,您可以采用rest语法
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``);