跳转到内容

编程风格

本章节着重探讨如何编写合理的、规范的、易于阅读和维护的代码。

块级作用域

let取代var

ES6 推出了 letconst 两个命令,用来声明变量,其中 let 可以完全取代 var ,因为两者之间没有本质的区别,且 let 没有副作用。例如 var 会导致变量提升,且没有作用域的概念。

全局常量和线程安全

const 声明的是常量,一旦声明,常量的值就不能改变。在声明时必须初始化,否则会报错。const 声明的变量只在声明所在的块级作用域内有效。用 const 声明有以下几个优点:

  • 提醒阅读者该变量不可更改
  • 符合函数式编程的思想,运算不能更改值,只能新建值
  • JavaScript编译器对 const 进行优化,有利于提高运行效率

字符串

静态字符串一律使用单引号,动态字符串一律使用反引号。

解构赋值

使用数组的成员、函数参数是对象成员、函数返回多个值时,使用解构赋值。

js
const arr = [1,2,3,4]
const [first, second] = arr

const fn = ({name: 'duyi', age: 18}) => {
  return {name, age}
}

对象

  1. 对象写成一行时,最后一个属性不以逗号结尾;写成多行时,最后一个属性以逗号结尾。
  2. 对象尽量静态化,如果要给对象新加值,尽可能通过 Object.assign 方法。
  3. 如果对象的属性名是动态的,可以在创造对象时使用属性表达式定义。
js
let obj = { a: 1, b: 2, c: 3 }
let obj = {
  a: 1,
  b: 2,
  c: 3,
}

数组

  1. 使用扩展运算符 ... 复制数组
  2. 使用 Array.from 将类数组对象或可遍历对象转化为数组

函数

  1. 立即执行函数、需要函数表达式的场合、Function.prototype.bind 应写成箭头函数的形式
  2. 所有配置项应集中在最后一个参数中,布尔值不能直接作为参数
  3. 不要在函数体内使用 arguments 变量,使用剩余运算符 ...args 代替
  4. 使用默认值语法给参数设置默认值

Map结构

需要模拟实体对象时才用 Object,只需要 key.value 数据结构时,使用 Map 结构。因为 MapIterator 接口,可以用 for...of 循环遍历。

class

用 Class 取代需要 prototype 的操作,因为 Class 的写法更简洁。使用 extends 取代 prototype 的操作 实现继承,这样不会存在 instanceof 运算危险。

模块

坚持使用 Module 模块写法,使用 import 取代 require 。如果模块只有一个输出值,就使用 export default ,如果有多个输出值,就不使用 export defaultexport default 与普通的 export 不可以同时使用。不要在模块输入中使用通配符,这样可以确保模块的依赖关系清晰。

总结

编写高质量代码应遵循以下风格指南:

  1. 变量声明:优先使用letconst代替var,以支持块级作用域和避免变量提升问题。const用于声明常量,提高代码的不可变性和线程安全性。

  2. 字符串:静态字符串使用单引号,动态字符串使用模板字符串(反引号)。

  3. 解构赋值:在处理数组元素、对象属性和函数参数时使用解构赋值,以简化代码和提高可读性。

  4. 对象:对象字面量在多行时应以逗号结尾;尽量静态化对象,动态属性名使用属性表达式。

  5. 数组:使用扩展运算符和Array.from进行数组操作。

  6. 函数:使用箭头函数、集中配置参数、剩余参数和默认参数值来简化函数定义。

  7. 数据结构:优先使用Map而非Object,因为Map是迭代器,支持for...of循环。

  8. :使用class语法简化原型操作,使用extends实现继承。

  9. 模块:坚持使用ES6模块语法,importexport优于requiremodule.exports。单一输出值使用export default,多个值不使用export default

遵循这些风格指南有助于编写易于阅读和维护的代码。