带有 ForEach 的模板字面量

25
在模板字面量中,是否可以返回一个字符串值以便它被添加在那个位置上?因为如果我记录它,它会返回undefined。或者像我输入的那样完全不可能吗?

ForEach中返回一个字符串值以便它被添加在那个位置上是可能的吗?因为如果我记录它,它会返回undefined。还是说完全不可能?

return `<div>
                <form id='changeExchangeForViewing'>
    <label for='choiceExchangeForLoading'>Change the exchange</label>
    <div class='form-inline'>
    <select id='choiceExchangeForLoading' name='choiceExchangeForLoading' class='form-control'>

    ${Object.keys(obj).forEach(function (key) {
        return "<option value='" + key + "'>" + obj[key] + "</option>"           
    })}
    `;

1
与我下面的评论相关:https://jsfiddle.net/Lwt6aLyp/1/ - user8897421
2个回答

61
不可以,因为forEach会忽略其回调函数的返回值并且从不返回任何内容(因此,调用它会导致undefined)。
你需要使用map,它正好做你想做的事情:
return `<div>
    <form id='changeExchangeForViewing'>
        <label for='choiceExchangeForLoading'>Change the exchange</label>
        <div class='form-inline'>
            <select id='choiceExchangeForLoading' name='choiceExchangeForLoading' class='form-control'>
                ${Object.keys(obj).map(function (key) {
                    return "<option value='" + key + "'>" + obj[key] + "</option>"
                }).join("")}
`;

请注意,映射后,该代码使用.join("")从数组中获取单个字符串(不带任何分隔符)。(我一开始忘了这个 - 做了太多的React东西 - 但stephledev他/她的回答中指出了这一点。) 话虽如此,如果你将其分开阅读,可能会更容易理解,并且可以使用箭头函数而不是传统函数,也许还有另一个模板文字:
const options = Object.keys(obj).map((key) =>
    `<option value='${key}'>${obj[key]}</option>`
);
return `<div>
    <form id='changeExchangeForViewing'>
        <label for='choiceExchangeForLoading'>Change the exchange</label>
        <div class='form-inline'>
            <select id='choiceExchangeForLoading' name='choiceExchangeForLoading' class='form-control'>
                ${options.join("")}
`;

最后,我会提到 Object.entries,它可以给你一个由 [key, value] 数组组成的箭头,你 可能 想要在映射选项时使用它(或者不用,Object.keys 也可以):

const options = Object.entries(obj).map((key, value) =>
    `<option value='${key}'>${value}</option>`
);
return `<div>
    <form id='changeExchangeForViewing'>
        <label for='choiceExchangeForLoading'>Change the exchange</label>
        <div class='form-inline'>
            <select id='choiceExchangeForLoading' name='choiceExchangeForLoading' class='form-control'>
                ${options.join("")}
`;

顺便提一下:那不是一个“字符串文字”,它是一个模板文字


1
我认为有大约15分钟的时间你无法接受。 - mdatsev
1
@nitte93user3232918 我需要等待9分钟。 - Steven
2
我建议将代码移动到一个函数中,以保持整洁,并且可以在回调函数内使用单独的模板字面量。 - user8897421
1
@rockstar:是的,我完全同意。 - T.J. Crowder
1
由于调用 forEach 的结果始终为 undefined,但调用 map 的结果是具有映射内容的数组。 - T.J. Crowder
显示剩余3条评论

20

由于map()返回一个数组,因此@T.J.Crowder的答案会生成无效的HTML,因为在模板字面量中调用了数组的toString()方法来使用逗号作为分隔符。为了解决这个问题,只需附加join('')来明确地不使用分隔符:

${Object.keys(obj).map(key => (
    `<option value="${key}">${obj[key]}</option>`
)).join('')}

此外,您可以在映射内部使用模板文字。


2
当你发现一个小错误时,最好的做法是评论并让回答者知道。Stack Overflow旨在协作解决问题。(最近我一直在做React!) - T.J. Crowder
提醒一下,如果有人在阅读stephledev答案下的评论,请注意修复已经整合到被接受的答案中,所以这里没有什么可看的。 ;) - bugmenot123
字面值方面,这正是我所需要的。 - sg28

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接