使用 map() 的意外逗号
Posted
技术标签:
【中文标题】使用 map() 的意外逗号【英文标题】:Unexpected comma using map() 【发布时间】:2018-01-30 10:00:24 【问题描述】:我有一个包含元素列表的数组,我正在尝试使用模板字符串将此列表附加到 html 元素:
var description = [
'HTML & CSS',
'javascript object-oriented programming',
'Progressive Web apps (PWAs)',
'Website Performance Optimization',
'Webpack and Gulp workflows',
'Fullstack React.js',
'Web Components',
'Responsive web design',
'Sketch design',
'GraphQL and Relay'
]
$('body').append(
`
<div class="description">
<ul>
$description.map(
function(work)
return `<li>$work</li>`
)</ul>
</div>
`
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
因此,我在每个列表元素之间得到了一个意外的逗号。 (运行上面的代码sn-p就可以看到了。)
我怎样才能避免这种情况?
【问题讨论】:
map()
函数没问题。问题应该来自其他地方
看起来你在这里使用了某种模板语言;哪一个?
我在这里使用纯 JS (ES2015)(只是一个 jQuery 选择到正文并附加元素)。在描述中添加了一个 sn-p。
@CBroe:这些是 ES2015+ template literals。
【参考方案1】:
说明
template literals 使用toString()
方法,默认情况下将map
返回的数组与,
连接起来。
为了避免这个“问题”,你可以使用join('')
代码
var description = [
'HTML & CSS',
'Javascript object-oriented programming',
'Progressive Web apps (PWAs)',
'Website Performance Optimization',
'Webpack and Gulp workflows',
'Fullstack React.js',
'Web Components',
'Responsive web design',
'Sketch design',
'GraphQL and Relay'
]
$('body').append(
`
<div class="description">
<ul>
$
description.map(function(work)
return `<li>$work</li>`
).join('')
</ul>
</div>
`
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
【讨论】:
哇,真不敢相信我忘了join()
我的阵列。谢谢哈哈!
我想知道这个被接受的答案如何与下面的其他答案在同一分钟内【参考方案2】:
.map()
返回一个数组。您可能希望返回一个包含串联在一起的数组元素的 string。你可以通过.join('')
做到这一点:
var description = [
'HTML & CSS',
'Javascript object-oriented programming',
'Progressive Web apps (PWAs)',
'Website Performance Optimization',
'Webpack and Gulp workflows',
'Fullstack React.js',
'Web Components',
'Responsive web design',
'Sketch design',
'GraphQL and Relay'
]
$('body').append(
`
<div class="description">
<ul>
$description.map(
function(work)
return `<li>$work</li>`
).join('') /* added .join('') here */</ul>
</div>
`
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
【讨论】:
map如何返回数组?我们已经告诉它返回一个模板字面量,对吧? 你能澄清你在问什么吗?.map
总是返回一个数组。我们不能告诉它返回一个模板字面量,也不能在这里这样做。
``` $description.map( function(work) return <li>$work</li>
``` 这里我们返回的是模板字面量<li>$work</li>
对吧?那么它又是如何转换成数组的呢? ?
您正在查看来自 回调 的 return
,而不是来自 array.map
本身。 array.map
方法创建一个新数组,然后遍历现有数组,在每个元素上调用回调函数,然后将回调返回的任何值推送到新数组。最后,它返回新数组。下面是一个简单的示例,您可以在浏览器的开发工具中尝试:let a = [5,10,15]; let b = a.map( function(x) return -x; ); console.log(a); console.log(b);
如您所见,回调中的 return
语句返回一个数字,但 map
将所有这些都收集到一个新数组中。【参考方案3】:
正如其他人所指出的(为了完整起见,我将重复一遍),Array.prototype.map
返回一个新数组,其中包含在传递给它的函数中更改的元素。
当您将数组连接到字符串时(这就是这里发生的情况),它也会将数组转换为字符串。并且当数组转换为字符串时,会自动使用逗号连接。
const arr = ['<a>', '<b>'];
console.log(arr + ""); // <a>,<b>
除了使用.join()
显式传递一个空字符串作为分隔符之外,您还可以将.map()
替换为Array.prototype.reduce
以将数组缩减为单个值。
description.reduce((acc, work) => acc + `<li>$work</li>`, '')
所以完整的代码应该是这样的:
var description = [
'HTML & CSS',
'Javascript object-oriented programming',
'Progressive Web apps (PWAs)',
'Website Performance Optimization',
'Webpack and Gulp workflows',
'Fullstack React.js',
'Web Components',
'Responsive web design',
'Sketch design',
'GraphQL and Relay'
]
$('body').append(
`
<div class="description">
<ul>
$
description.reduce((acc, work) => acc + `<li>$work</li>`, '')
</ul>
</div>
`
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
【讨论】:
【参考方案4】:为了简单的代码,我只是这样使用:
$description.map((work) => <li>$work</li>
).join('')
【讨论】:
这更适合作为评论,而不是答案。因为它没有澄清 OP 的原始问题。而是引入了不同的语法。以上是关于使用 map() 的意外逗号的主要内容,如果未能解决你的问题,请参考以下文章
为啥在 innerHTML 中使用的 Array#map 输出中的额外逗号?