javascript - 重写这行javascript
问题描述
在https://codepen.io/kurt_cagle/pen/xqoMBG我找到了一个带有以下语句的函数 walkData:
var buf = Object.keys(data).map((key)=>`<details><summary id="${key}" ${Object.keys(data[key]).map((subkey)=>{return subkey != 'children'?`data-${subkey}="${data[key][subkey]}"`:' '}).join(' ')}><img class="icon" src="${me.imageBase}${data[key].icon?data[key].icon:data[key].children?'Folder.png':'Item.png'}"> </img>${data[key].label}</summary>
${data[key].children?me.walkData(data[key].children):""}</details>`);
作为一个老式的非功能恐龙,我发现地图和插值是一团糟,几乎不可能跟随、调试或修改。codepen“格式化Javascript”按钮有帮助,但还不够。(我会在这里发布,但格式让我失望)
是否可以将其重新设计为使用手写循环、中间变量和较短的行,理想情况下它们只做一件事。
作为一个附带问题,那一行中有四个`,谁能向我解释一下js是如何解析它的?
解决方案
我保留了您的原始代码,只是添加了适当的换行符和缩进。
我添加的只是:
- 要渲染到的目标元素
data
我使用该功能进行逆向工程的一些假货walkData
一个只返回“CHILDREN”的假函数......
注意:我实际上可以稍微改进此代码并删除<img>
元素的结束标记,因为这些是不必要的。subkey
map 函数也是单行函数,因此它实际上可以转换为不带大括号或显式 ; 的lambda return
。就像key
它外面的映射器一样。
例子
我一点点格式化有很长的路要走。模板文字很棒,因为您不必处理混乱的字符串连接。
const data = {
'a': { label: 'Directory A', children: [] },
'b': { label: 'File B', children: null }
}
const me = {
imageBase: '/',
walkData: (children) => 'CHILDREN'
}
const buf = Object.keys(data).map((key) => `
<details>
<summary
id="${key}" ${Object.keys(data[key]).map((subkey) => {
return subkey != 'children'
? `data-${subkey}="${data[key][subkey]}"` : ' '
}).join(' ')}>
<img class="icon"
src="${me.imageBase}${data[key].icon
? data[key].icon : data[key].children
? 'Folder.png' : 'Item.png'}">
</img>
${data[key].label}
</summary>
${data[key].children ? me.walkData(data[key].children) : ""}
</details>
`)
document.getElementById('target').innerHTML = buf.join('')
<div id="target"></div>
更新
这是另一个具有单独函数调用和注释的版本。它在功能上与前面的代码相同。
没有明确return
的陈述,因为所有的 lambda 都是单行的。
const data = {
'a': { label: 'Directory A', children: [] },
'b': { label: 'File B', children: null }
}
const me = {
imageBase: '/',
walkData: children => 'CHILDREN'
}
const main = () => {
document.getElementById('target').innerHTML = render(data)
}
const render = data =>
Object.keys(data).map(key =>
renderDetails(key, data)).join('')
const renderDetails = (key, data) =>
`<details>
<summary id="${key}" ${renderDataAttributes(data[key])}>
<img class="icon" src="${renderImageSource(data[key])}">
</img>
${data[key].label}
</summary>
${data[key].children ? me.walkData(data[key].children) : ""}
</details>`
const renderDataAttributes = detail =>
Object.keys(detail)
.filter(key => key !== 'children') // Filter-out children
.map(key => `data-${key}="${detail[key]}"`) // Map to a data attr
.join(' ') // Join the values
const renderImageSource = detail =>
me.imageBase + (
detail.icon /* If the detail has an icon, */
? detail.icon /* Use the defined icon */
: detail.children /* Else, does it have children? */
? 'Folder.png' /* If so, it's directory */
: 'Item.png' /* Else, it's a file */
)
main()
<div id="target"></div>
推荐阅读
- google-maps - Location/GeoLocator/GeoLocation 没有返回我的纬度和经度
- oracle - oracle 语句中的 TRUSTED/UNTRUSTED 关键字
- javascript - JavaScript 可以实现并行性吗?
- c++ - 将字符串向量移动到另一个字符串向量
- concurrency - 如何在负载运行器场景中计算以下任务的平均用户并发?有人能帮我吗?
- python - 通过加倍和连接来“扁平化”熊猫数据框?
- javascript - .find() 方法:我如何返回一个布尔值而不是我找到的对象?
- vue.js - 我想在本地使用Vue,但它不起作用
- css - CSS布局:如何在N个元素之后打破第一列,并在第二列中跟随,仅使用CSS?
- node.js - 每次更改使用的默认 Node 版本时是否需要“npm install”?