
使用 `for…in` 遍历 `textarea.value.split(“n”)` 会返回数组索引而非实际行内容,导致序列化结果错误;应改用传统 `for` 循环、`for…of` 或 `foreach` 来访问每行字符串。
在处理
for (var line in textarea.value.split("n")) { console.log(line); // 输出 "0", "1", "2", "3" —— 这是数组索引,不是行内容! }
for…in 语句设计用于枚举对象的可枚举属性名(包括数组的数字索引),而非遍历数组元素。因此,textarea.value.split(“n”) 返回的是类似 [“key1: “, “key2: 0”, “key3: “, “key4: 0”] 的数组,而 for…in 实际迭代的是 “0”, “1”, “2”, “3” 这些字符串形式的索引 —— 这正是你看到 {“0”: “”, “1”: “”, …} 的根本原因。
✅ 正确做法:使用语义明确的数组遍历方式:
方案 1:传统 for 循环(兼容性最佳)
const lines = textarea.value.split("n"); let json = "{n"; for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (!line) continue; // 跳过空行 const [key, ...rest] = line.split(": "); const value = rest.join(": ").trim(); // 处理值中含冒号的情况 json += ` "${key.trim()}": "${value}",n`; } json = json.replace(/,n$/, "n}"); // 替换末尾逗号并闭合大括号
方案 2:for...of(推荐,语义清晰)
const lines = textarea.value.split("n"); const entries = []; for (const line of lines) { const trimmed = line.trim(); if (!trimmed) continue; const [key, ...rest] = trimmed.split(": "); entries.push(` "${key.trim()}": "${rest.join(": ").trim()}"`); } const json = "{n" + entries.join(",n") + "n}";
方案 3:函数式写法(简洁、可读性强)
const json = "{n" + textarea.value .split("n") .map(line => line.trim()) .filter(line => line) .map(line => { const [key, ...rest] = line.split(": "); return ` "${key.trim()}": "${rest.join(": ").trim()}"`; }) .join(",n") + "n}";
⚠️ 注意事项:
- 始终对每行调用 .trim(),避免前后空白符干扰解析;
- 使用 split(": ") 时需注意值本身可能含 ": "(如 "description": "A key: value example"),建议用 indexOf(": ") 或正则更稳健地分割;
- 若原始 JSON 结构复杂,建议直接操作 javaScript 对象而非逆向解析 textarea 文本——textarea 应仅作展示层,数据流应保持单向(对象 → 字符串 → textarea;用户修改后 → 重新解析 → 对象);
- 现代开发中,优先使用 const/let 替代 var,避免变量提升与作用域问题。
总结:for...in 不适用于数组遍历。牢记「for...in 遍历键(索引),for...of / forEach / for (let i=0;...) 遍历值」这一原则,即可避免此类低级但高发的逻辑错误。