Skip to Content
JavaScript前端JS规范

前端 JS 规范

前端不参与金额计算

  • 前端由于 JS 天生的计算精度问题会导致计算结果不复合预期。因此,所有数值计算类全部交由服务端开发统一计算,前端只做透传,不做任何计算

  • 金额前端保存,必须使用 string 类型,前端请求服务端传参,涉及到金额字段必须使用 string 传递(禁止使用 number 类型)以此避免 number 类型的值 可能会在表示数值区间外数据溢出 还有 当数值过大默认转为科学计算法显示 的问题。

不使用双等号进行判断

JavaScript 中使用两等号会因为 隐式类型转换 而导致结果和预期不符,进而导致程序 bug,例如:

"10" == 10; // true null == undefined; // true "" == 0; // true true == 1; // true false == 0; // true
  • 判断是否相等请使用 ===,请勿使用 ==
  • 判断是否不相等请使用 !==,请勿使用 !=

危险的内置函数需要 catch

一些内置函数对不当的参数会抛错,导致功能不可用,严重甚至白屏:

  • JSON.parse 当接收一个不能被反序列化的字符串时会抛错
JSON.parse("{sum: 123},"); // Uncaught SyntaxError: Expected property name or '}' in JSON at position 1
// ✅ good case // 将 JSON.parse 封装成通用的 jsonParseSafely export function jsonParseSafely<T>(str: string, defaultValue: any = {}): T { try { return JSON.parse(str); } catch (error) { console.warn("JSON.parse", str, "failed", error); return defaultValue; } } // 在业务代码中使用 jsonParseSafely 而非 JSON.parse const jsonData = jsonParseSafely(data.jsonData || "[]");
  • decodeURIComponent 如果 encodedURI 包含一个 % 后面不跟随两个十六进制数字,或者转义序列没有编码有效的 UTF-8 字符,则会抛出 URIError 异常
decodeURIComponent("%="); // Uncaught URIError: URI malformed
  • JSON.stringify 当被序列化对象存在 循环引用 或者 BigInt 类型属性时,会抛出 TypeError
// JSON.stringify 处理循环引用 var obj1 = {}; var obj2 = {}; obj1.prop = obj2; obj2.prop = obj1; JSON.stringify(obj1); // Uncaught TypeError: Converting circular structure to JSON // JSON.stringify 处理 BigInt var obj = { num: BigInt(123456), }; JSON.stringify(obj); // Uncaught TypeError: Do not know how to serialize a BigInt

避免直接访问嵌套属性

访问层级过深的属性容易引起空指针,导致页面白屏等严重错误。

  • 优先推荐 TS 可选级联语法,即 Optional Chaining:props?.maybeObj?.a,但是请勿滥用,滥用的坏处在于
    • 在本来该进行错误处理的地方,用这种方式绕过
    • 本来应该能监控发现问题的地方,被这种方式掩盖掉
    • 让 undefined 继续传递下去,引发更深层次的问题
  • 若变量缺少类型定义则使用 lodash.get

业务场景下禁止使用客户端时间

  • 客户端时间可被用户随意更改,任何与日期时间相关的业务逻辑都必须采用服务端下发的时间

禁止使用 JS 保留字 和 浏览器全局变量 作为变量和模块名

  • 使用 JS 保留字 和 浏览器全局变量 作为变量和模块名可能导致不可预知的问题

避免在 this 上随意添加属性

  • 在 this 上随意挂载属性可能会覆盖内置属性导致不可预期的运行时错误,如果必须加则应当使用 $_ 前缀
Last updated on