Node.js SyntaxError: Unexpected identifier:非 ASCII 字符混入代码的排查

中文字符导致 SyntaxError

SyntaxError: Unexpected identifier '目'
    at wrapSafe (node:internal/modules/cjs/loader:...)

报错指向中文字符”目”,不是代码写法问题,而是文本内容被误粘贴进了 JS 文件

// 错误:文本直接出现在代码里
const text = fs.readFileSync("1.txt", "utf8");
console.log(text.length);

   AI辅助的全方位科研管理与创作平台   // ← 这行是数据,不是代码

最后一行是从 1.txt 复制过来的内容,Node 解析时把它当代码执行,“题”和”目”之间有空格被当作两个标识符。

修复方法:删除误粘贴的文本,JS 文件只保留代码逻辑。

readFileSync 的编码参数

// 不指定编码:返回 Buffer
const buf = fs.readFileSync("1.txt");
console.log(buf.length);         // 字节数(中文 UTF-8 每字 3 字节)

// 指定 utf8:返回字符串
const text = fs.readFileSync("1.txt", "utf8");
console.log(text.length);        // 字符数(JavaScript 的 UTF-16 码元数)
console.log(Buffer.byteLength(text)); // UTF-8 字节数

中文字符用 buf.length 统计结果是字节数(通常是字符数的 3 倍),必须指定 "utf8" 才能拿到字符串后再用 .length

用 Map 统计数组重复项

Map 是计数/去重的高效结构:

const arr = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple'];

const counter = new Map();
for (const item of arr) {
    counter.set(item, (counter.get(item) ?? 0) + 1);
}
// Map { 'apple' => 3, 'banana' => 2, 'cherry' => 1 }

找出出现超过 1 次的元素:

const duplicates = [...counter.entries()]
    .filter(([, count]) => count > 1)
    .map(([key]) => key);
// ['apple', 'banana']

一遍遍历即可,时间复杂度 O(n),比嵌套 filter/indexOf 更高效。

去重(保留唯一值)

Set 更简洁:

const unique = [...new Set(arr)];
// ['apple', 'banana', 'cherry']

如果同时需要计数和去重,先建 Map 再从 Map 的 key 拿唯一值:

const unique = [...counter.keys()];