Skip to content

JavaScript最佳实践 ​

1. 变量 ​

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

2. 条件 ​

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

3. 循环 ​

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

4. 类型 ​

4.1 类型检测 ​

[建议] 类型检测优先使用 typeof。对象类型检测使用 instanceof。null 或 undefined 的检测使用 == 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 ​

[建议] 定义模块时不要指明 id 和 dependencies。 ​
[建议] 使用 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 样式获取 ​

[建议] 获取元素实际样式信息时,应使用 getComputedStyle 或 currentStyle。 ​

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.