前端 代码 整洁之道
1. 前言
ES6 新增了很多语法和语法糖,在使用这些语法和语法糖的时候我们可以让我们的 代码 更加优雅。另外,在程序上有一些约定俗成的东西,这样会帮助我们更好地书写和阅读 代码 。本节我们将学习前端 代码 的整洁之道帮助你更好地书写你的 代码 。
2. 变量的使用
2.1 命名
在定义变量时最好使用驼峰命名(如:aaBbCc)的方式,并且要使用有准确意义的变量名,这样容易阅读。
// bad var getname = function ( ) { return 'imooc' ; } // good var getName = function ( ) { return 'imooc' ; }
在声明变量时不要 添加 没必要的上下文,如果你的类 名称 / 对象 名称 已经说明了它们是什么,不要在 ( 属性 ) 变量名里重复。
// bad const dog = { dogType : '斗牛犬' dogColor : '黑色' , } ; dog . dogType = '牧羊犬' // good const dog = { type : '斗牛犬' color : '黑色' , } ; dog . type = '牧羊犬'
2.2 let 和 const 的选择
ES6 提出了两个新的声明变量的命令: let 和 const 用于代替 var,使用 let 来声明可变变量,使用 const 来声明常量。对于全局环境下的常量,变量名可以使用纯大写加下划线的方式命名。
let name = 'xiaoming' ; name = 'Jack' ; const PI_COUNT = ; { const lession = 'ES6 Wiki' ; console . log ( lession ) ; }
在选择 let 和 const 时,优先使用 const ,尤其是在全局环境,不应该设置变量,只应设置常量。
const 比 let 好的几个原因。
@H_ 404 _223@ 不会对值产生副作用,也就是值被 修改 ,告诉开发者此变量不能被 修改 ; const 比较符合 函数 式编程思想,运算不改变值,只是新建值; JavaScript 编译器会对 const 进行优化,所以多使用 const ,有利于提高程序的运行效率,也就是说 let 和 const 的本质区别,其实是编译器内部的处理不同。
在作用域内声明的变量需要使用,如果下文没有用到就不要声明。
// bad const name = 'xiaoming' ; // 下文没有使用就不要定义了 // good const name = 'xiaoming' ; console . log ( name ) ;
2.3 字符串
对于静态字符串一律使用单引号,不使用双引号。在拼接字符串的时候需要使用反引号的方式,更加易于阅读。
// bad const name = "imooc" ; const info = name + ' ES6 Wiki' ; // good const name = 'imooc' ; const info = ` ${ name } ES6 Wiki` ;
2.4 解构赋值
在批量定义有 默 认值的变量时可以使用数组的解构赋值。
// bad const a = , b = , c = ; // good const [ a , b , c ] = [ , , ] ;
在 获取 数组或对象中值时也可以优先使用解构的方式:
const arr = [ , , , ] ; const obj = { a : , b : } ; // bad const x = arr [ ] ; const y = arr [ ] ; const a = obj . a ; const b = obj . b ; // good const [ x , y ] = arr ; const [ a , b ] = obj ;
在 函数 参数中,如果 函数 接收的参数是 一个 对象时,可以直接在 函数 的括号中解构对象,这样可以在 函数 内部之间使用变量。
// bad function getFullName ( user ) { const f irs tName = user . f irs tName ; const lastName = user . lastName ; } // good function getFullName ( obj ) { const { f irs tName , lastName } = obj ; } // best function getFullName ( { f irs tName , lastName } ) { }
对于 函数 中有返回值是对象时,对象中 属性 名和要返回的变量名相同时可以省了变量。
// bad function foo ( ) { const a = 'aaa' ; const b = 'bbb' ; return { a : a , b : b } } // good function foo ( ) { const a = 'aaa' ; const b = 'bbb' ; return { a , b } }
2.5 尽量减少使用条件语法
在条件语句中,可以使用或( || )运算符来设置有 默 认值的变量。
// bad function createPerson ( name ) { var newName ; if ( name ) { newName = name ; } else { newName = 'Jack' ; } } // good function createPerson ( name ) { const newName = name || 'Jack' ; }
如果符合条件运算符( ?: )那就尽量使用条件运算符。
const age = ; // bad let status = '' if ( age > ) { status = '成年人' } else { status = '未成年' } // good const status = age > ? '成年人' : '未成年' ;
3. 函数
3.1 使用箭头 函数
在定义匿名 函数 时最好使用箭头 函数 的形式,更加简洁。
// bad const foo = function ( ) { } ( function ( ) { console . log ( '100' ) } ) ( ) // good const foo = ( ) => { } ( ( ) => { console . log ( '100' ) } ) ( ) // best [ , , ] . map ( x => x * x ) ;
当 函数 只有 一个 参数,并且返回值是 一个 表达式时,可以将参数外的括号和表达式外的大括号都省略。
// bad [ , , ] . map ( ( x ) => { return x * x ; } ) ; // good [ , , ] . map ( x => x * x ) ;
使用箭头 函数 的另 一个 好处是,在箭头 函数 内部是不绑定 this 的,这样在 调用 函数 时 this 的指向是不会变的。
var title = "全局 标题 " ; // bad var imooc = { title : "网 ES6 Wiki" , getTitle : function ( ) { console . log ( this . title ) ; } } ; imooc . getTitle ( ) ; // 网 ES6 Wiki var bar = imooc . getTitle ; bar ( ) ; // 全局 标题 // good var imooc = { title : "网 ES6 Wiki" , getTitle : ( ) => { console . log ( this . title ) ; } } ; imooc . getTitle ( ) ; // 全局 标题 var bar = imooc . getTitle ; bar ( ) ; // 全局 标题
3.2 函数 参数
在 函数 传参时,参数不要超过两个,这样会让你更容易测试这个 函数 ,如果超过 2 个参数会导致组合膨胀,以至于你必须根据不同的参数对大量不同的情况进行测试。理想情况下是两个,如果参数过多可以使用对象来处理。
// bad function fn ( a , b , c , d ) { // t odo } // good const p ara ms = { a : , b : , c : , d : true } function fn ( p ara ms ) { // t odo }
不要使用 函数 的内部的参数 arguments 来 获取 函数 的不定参数,使用 ... 来接收。因为 arguments 获取 的参数是 一个 类数组需要转化为真正的数组。
function foo ( ) { const args = [ ] . slice . call ( arguments ) ; console . log ( args ) } foo ( , , ) ; // [1,2,3] function foo ( ... args ) { console . log ( args ) } foo ( , , ) ; // [1,2,3]
当 函数 的参数有 默 认值时,可以使用最短路径的 方法 设置。
// bad function foo ( a , b ) { a = a || ; b = b || ; } // good function foo ( a = , b = ) { // t odo }
3.3 一个 函数 只做一件事
一个 函数 最好只做一件事,这是软件工程中最重要的原则。如果 函数 做了较多的事情,它就难以组合、测试和推测。当你让 函数 只做一件事情的时候,它们就很容易重构,而且 代码 读起来也会清晰得多。
// bad function foo ( p ara ms ) { p ara ms . forEach ( p ara m => { let p ara m1 = fun1 ( p ara m ) ; if ( p ara m1 . isActive ) { email ( client ) ; } } ) ; } // good function foo ( p ara ms ) { p ara ms . forEach ( p ara m => { step1 ( p ara m ) } ) ; } function step1 ( p ara m ) { if ( foo2 ( p ara m ) ) { email ( client ) ; } } function step2 ( p ara m ) { return fun1 ( p ara m ) . isActive }
上文中我们提到了在定义变量时要有意义,从命名就可以知道表达什么意思,所以在定义 函数 名时要有意义。
// bad function foo ( ) { } // good function setTitle ( ) { }
3. 小结
本节我们从几个方向入手通过好的写法与不好的写法进行对比,可以窥探到程序的优雅,多使用好的规范的写法养成 代码 规范的好习惯。