Skip to content

JavaScript最佳实践

1. 变量

[强制] 变量在使用前必须通过 var 定义。
[强制] 每个 var 只能声明一个变量。
[强制] 变量必须 即用即声明,不得在函数或其它形式的代码块起始位置统一声明所有变量。

2. 条件

[强制] 在 Equality Expression 中使用类型严格的 ===。仅当判断 null 或 undefined 时,允许使用 == null
[建议] 尽可能使用简洁的表达式。
[建议] 按执行频率排列分支的顺序。
[建议] 对于相同变量或表达式的多值条件,用 switch 代替 if
[建议] 如果函数或全局中的 else 块后没有任何语句,可以删除 else

3. 循环

[建议] 不要在循环体中包含函数表达式,事先将函数提取到循环体外。
[建议] 对循环内多次使用的不变值,在循环外用变量缓存。
[建议] 对有序集合进行遍历时,缓存 length
[建议] 对有序集合进行顺序无关的遍历时,使用逆序遍历。

4. 类型

4.1 类型检测

[建议] 类型检测优先使用 typeof。对象类型检测使用 instanceofnullundefined 的检测使用 == null

4.2 类型转换

[建议] 转换成 string 时,使用 + ''
[建议] 转换成 number 时,通常使用 +
[建议] string 转换成 number,要转换的字符串结尾包含非数字并期望忽略时,使用 parseInt
[强制] 使用 parseInt 时,必须指定进制。
[建议] 转换成 boolean 时,使用 !!
[建议] number 去除小数点,使用 Math.floor / Math.round / Math.ceil,不使用 parseInt

5. 字符串

[强制] 字符串开头和结束使用单引号 '
[建议] 使用 数组+ 拼接字符串。
[建议] 复杂的数据到视图字符串的转换过程,选用一种模板引擎。

6. 对象

[强制] 使用对象字面量 {} 创建新 Object
[强制] 对象创建时,如果一个对象的所有 属性 均可以不添加引号,则所有 属性 不得添加引号。
[强制] 对象创建时,如果任何一个 属性 需要添加引号,则所有 属性 必须添加 '
[强制] 不允许修改和扩展任何原生对象和宿主对象的原型。
[建议] 属性访问时,尽量使用 .
[建议] for in 遍历对象时, 使用 hasOwnProperty 过滤掉原型中的属性。

7. 数组

[强制] 使用数组字面量 [] 创建新数组,除非想要创建的是指定长度的数组。
[强制] 遍历数组不使用 for in
[建议] 不因为性能的原因自己实现数组排序功能,尽量使用数组的 sort 方法。
[建议] 清空数组使用 .length = 0

8. 函数

8.1 函数长度

[建议] 一个函数的长度控制在 50 行以内。

8.2 参数设计

[建议] 一个函数的参数控制在 6 个以内。
[建议] 通过 options 参数传递非数据输入型参数。

8.3 闭包

[建议] 在适当的时候将闭包内大对象置为 null
[建议] 使用 IIFE 避免 Lift 效应

8.4 空函数

[建议] 空函数不使用 new Function() 的形式。
[建议] 对于性能有高要求的场合,建议存在一个空函数的常量,供多处使用共享。

9. 面向对象

[强制] 类的继承方案,实现时需要修正 constructor
[建议] 声明类时,保证 constructor 的正确性。
[建议] 属性在构造函数中声明,方法在原型中声明。
[强制] 自定义事件的 事件名 必须全小写。
[强制] 自定义事件只能有一个 event 参数。如果事件需要传递较多信息,应仔细设计事件对象。
[建议] 设计自定义事件时,应考虑禁止默认行为。

10. 动态特性

10.1 eval

[强制] 避免使用直接 eval 函数。
[建议] 尽量避免使用 eval 函数。

10.2 动态执行代码

[建议] 使用 new Function 执行动态代码。

10.3 with

[建议] 尽量不要使用 with

10.4 delete

[建议] 减少 delete 的使用。
[建议] 处理 delete 可能产生的异常。

10.5 对象属性

[建议] 避免修改外部传入的对象。
[建议] 具备强类型的设计。

11. 浏览器环境

11.1 模块化

11.1.1 AMD

[强制] 使用 AMD 作为模块定义。
[强制] 模块 id 必须符合标准。

11.1.2 define

[建议] 定义模块时不要指明 iddependencies
[建议] 使用 return 来返回模块定义。

11.1.3 require

[强制] 全局运行环境中,require 必须以 async require 形式调用。
[强制] 模块定义中只允许使用 local require,不允许使用 global require
[强制] Package在实现时,内部模块的 require 必须使用 relative id
[建议] 不会被调用的依赖模块,在 factory 开始处统一 require

11.2 DOM

11.2.1 元素获取

[建议] 对于单个元素,尽可能使用 document.getElementById 获取,避免使用document.all
[建议] 对于多个元素的集合,尽可能使用 context.getElementsByTagName 获取。
[建议] 遍历元素集合时,尽量缓存集合长度。如需多次操作同一集合,则应将集合转为数组。
[建议] 获取元素的直接子元素时使用 children。避免使用childNodes

11.2.2 样式获取

[建议] 获取元素实际样式信息时,应使用 getComputedStylecurrentStyle

11.2.3 样式设置

[建议] 尽可能通过为元素添加预定义的 className 来改变元素样式,避免直接操作 style 设置。
[强制] 通过 style 对象设置元素样式时,对于带单位非 0 值的属性,不允许省略单位。

11.2.4 DOM 操作

[建议] 操作 DOM 时,尽量减少页面 reflow
[建议] 尽量减少 DOM 操作。

11.2.5 DOM 事件

[建议] 优先使用 addEventListener / attachEvent 绑定事件,避免直接在 HTML 属性中或 DOM 的 expando 属性绑定事件处理。
[建议] 使用 addEventListener 时第三个参数使用 false
[建议] 在没有事件自动管理的框架支持下,应持有监听器函数的引用,在适当时候(元素释放、页面卸载等)移除添加的监听器。

Released under the MIT License.