为何布尔值在ES模块与CommonJS中的表现存在差异?
问题分析:CommonJS脚本在ES模块中抛出TypeError的原因
问题场景
我编写了一个用于图遍历寻找最短路径的CommonJS脚本,通过二维数组visit记录节点是否被访问(元素值为true/false),初始化代码如下:
let visit = new Array(9); for (let i = 0; i <= 8; i++) { visit[i] = new Array(9); for (let j = 0; j <= 8; j++) { visit[i][j] = false; } }
随后设置根节点的访问状态:
visit[(rootNode[0], rootNode[1])] = true;
在运行过程中执行visit[x][y] = true;修改节点状态时,该脚本在CommonJS环境可正常输出结果,但在ES模块中抛出错误:
TypeError: Cannot create property '1' on boolean 'true'
其中1为被访问节点的x值,为何两者表现不同?
核心原因
1. 严格模式的差异
ES模块默认启用严格模式,而CommonJS默认不启用严格模式(除非手动添加'use strict';声明),这导致两者对错误代码的容错逻辑不同。
2. 代码中的关键笔误
设置根节点状态的代码里,visit[(rootNode[0], rootNode[1])] = true; 使用了逗号运算符——逗号运算符会返回最后一个表达式的值,因此这行代码等价于visit[rootNode[1]] = true;,也就是把visit数组中索引为rootNode[1]的元素直接赋值为true,而非给二维数组的[rootNode[0]][rootNode[1]]位置赋值。
当后续执行visit[x][y] = true;时:
- 在非严格模式的CommonJS中,JavaScript会隐式将布尔值
true包装成Boolean对象,允许给这个对象添加属性,因此不会抛出错误(但这完全不符合业务逻辑,只是表面"正常")。 - 在严格模式的ES模块中,禁止给原始值(如布尔值)添加属性,直接抛出
TypeError,即你遇到的错误。
修复方案
将设置根节点状态的代码修正为正确的二维数组访问方式:
visit[rootNode[0]][rootNode[1]] = true;
修复后,代码在CommonJS和ES模块环境中均可正常运行。
内容的提问来源于stack exchange,提问作者Jacob G
相关产品推荐
相关产品推荐

