JavaScript 类型转换与调试:从输入值到可靠判断
本文目录
旧笔记常把 parseInt、Number、Boolean 当作互换的“转类型函数”,这会把脏输入悄悄变成有效业务数据。可靠的处理顺序是先定义输入契约,再做显式转换,最后检查范围与业务约束。
Number 与 parseInt 不是一回事
Number(value) 尝试把整个值转换为数字;不能完整转换时得到 NaN。parseInt(value, 10) 则从字符串开头解析整数,遇到第一个不合法字符就停止,所以 parseInt('24px', 10) 得到 24,而 Number('24px') 得到 NaN。处理 CSS 长度时前者可能有用,处理用户提交的金额或数量时,这种“前缀合法就通过”的行为通常不够严格。
还有一个容易踩的边界:Number('') 和 Number(' ') 会得到 0。因此先判断空字符串,再转换;之后用 Number.isFinite 排除 NaN 与正负无穷,按业务检查整数、上下限和单位。金额不要依赖二进制浮点的精确小数运算,可用最小货币单位整数或经过审查的十进制库。
function parseQuantity(raw) {
const text = String(raw).trim();
if (text === '') return { ok: false, reason: '请输入数量' };
const value = Number(text);
if (!Number.isSafeInteger(value) || value < 1 || value > 10000) {
return { ok: false, reason: '数量必须是 1 到 10000 的整数' };
}
return { ok: true, value };
}
parseInt('24px', 10); // 24:只解析可识别的整数前缀
Number('24px'); // NaN:整个字符串不是数字
Number(''); // 0:空值必须在转换前单独处理
若输入必须是十进制整数文本,可以先用明确的格式规则检查整串,再转成 Number;不能把正则当作服务器端校验的替代品。
真值不等于“有业务值”
Boolean(value) 使用 JavaScript 真值规则。空数组、空对象都为真;字符串 '0' 也为真;0、''、null、undefined、NaN 为假。用 if (items.length) 判断数组是否非空是清楚的;用 if (items) 就不是。用 value || fallback 会把合法的 0 和空字符串一并替换,默认值应按语义选择 ??,并为表单空值单独定义规则。
NaN 有一个反直觉性质:NaN === NaN 为假。数字校验优先使用 Number.isNaN 或 Number.isFinite,不要用全局 isNaN 做严格输入判断,因为全局函数会先发生类型转换。需要严格相等语义时可了解 Object.is,但业务通常更应先验证数据形状。
参数、作用域与浏览器调试
函数接收参数时,原始值本身不会被调用方变量改写;对象参数传入的是对象引用值的副本,因此函数可通过该引用修改对象属性,但把形参重新赋值不会让调用方变量指向新对象。用不可变更新减少隐藏副作用,并在函数边界声明哪些值会被修改。
调试时先构造最小、可重复输入,再在 DevTools Sources 中设断点,逐步观察局部变量、调用栈和实际分支。对异步流程检查 Promise rejection、网络面板、请求 payload 和响应状态;临时 debugger 可以帮助定位,但提交前移除。控制台看到一个值不证明生产构建也走同一路径。
回归清单
- 空字符串、空白、0、负数、小数、超大整数和带单位字符串分别如何处理?
- 错误输入是否明确显示,而不是被转成 0、
NaN或默认值? - 是否需要保留 0、false 或空字符串作为合法值?
- 时间、金额、ID 是否用了匹配其精度和范围的表示方式?
- 浏览器和服务端是否都验证了同一业务约束,且服务端不信任客户端结果?
参考:MDN Number、MDN parseInt、MDN Truthy、MDN Number.isFinite、Chrome DevTools JavaScript debugging。
Live Notes
留言提交后会先进入审核,审核通过后对其他读者公开。