Object 转成字符串
✅ 8. 递归将 Object 转成字符串(HTML)形式
🧠 思路:
-
如果是字符串:直接返回
-
如果是数组:遍历拼接每个子元素(递归调用)
-
如果是对象:
- 拼接
<tag>children字符串</tag>
- 拼接
function render(node) {
if (typeof node === 'string') return node;
if (Array.isArray(node)) {
return node.map(render).join('');
}
// 是对象
const { tag, children = [] } = node;
return `<${tag}>${render(children)}</${tag}>`;
}
// 测试
const input = {
tag: 'div',
children: [
{
tag: 'span',
children: ['ssss']
},
{
tag: 'span',
children: [
{
tag: 'div',
children: ['aaaa']
}
]
},
['bbb']
]
};
console.log(render(input));
// 输出: <div><span>ssss</span><span><div>aaaa</div></span>bbb</div>
✅ 9. 把 HTML 字符串转成 Object(栈)
🧠 思路:
-
用正则解析出标签和文本
-
使用栈来维护父子关系
-
遇到:
<tag>
:入栈,新建节点</tag>
:出栈- 文本节点:添加到当前栈顶的
children
function parse(html) {
const tagRE = /<\/?([a-zA-Z]+)>|([^<>]+)/g;
const stack = [];
let root = null;
let match;
while ((match = tagRE.exec(html))) {
if (match[1]) {
const tag = match[1];
if (html[match.index + 1] !== '/') {
// <tag>
const node = { tag, children: [] };
if (stack.length > 0) {
stack[stack.length - 1].children.push(node);
} else {
root = node;
}
stack.push(node);
} else {
// </tag> 关闭标签,出栈
stack.pop();
}
} else if (match[2].trim()) {
// 文本节点
const text = match[2].trim();
if (stack.length > 0) {
stack[stack.length - 1].children.push(text);
}
}
}
return root;
}
// 测试
const html = `<div><span>ssss</span><span><div>aaaa</div></span>bbb</div>`;
console.log(JSON.stringify(parse(html), null, 2));
✅ 输出结构如下:
{
"tag": "div",
"children": [
{
"tag": "span",
"children": ["ssss"]
},
{
"tag": "span",
"children": [
{
"tag": "div",
"children": ["aaaa"]
}
]
},
"bbb"
]
}
如需支持属性、嵌套标签、换行缩进等,可以扩展语法和正则。需要我帮你扩展版本支持 <div class="foo">
或 prettier 格式化输出,也可以继续说。