良好的代码编程习惯是一个优秀的软件工程师的必备素养,也是一个团队开发易于阅读、高可维护性的大型项目的基础;虽然Javascript弱语言的本质给前端开发者带来了更大的灵活性,但从工程的角度来说这是非常不合理的,也是一个可维护性项目潜在的致命缺陷。为了避免出现‘‘连自己以前写过的代码都不忍睹视’’以及‘‘一个团队成员休假或离职,造成整个项目瘫痪’’的尴尬局面,对于一个大型项目而言,项目的代码风格,和项目的代码具有同等重要的地位。
1、良好的ES6新语法代码风格
- 1》块级作用域:
let
取代var
:提高js变量先声名、后定义的规范性(var存在变量提升,而let命令会因为暂时性死区报错,没有变量提升效果);const
优先于let
:①提醒代码阅读人该变量不应该修改;②被无意中修改时报错;(let、const的本质区别是编译器内部处理不同;Javascript编译器会对const进行优化,提升程序运行效率);
- 2》字符串:
- 静态字符串使用单引号
''
或者反引号,不适用双引号 - 动态字符串使用反引号+变量表达式;
- 静态字符串使用单引号
- 3》解构赋值
- 数组成员变量:使用数组成员变量时,优先使用解构赋值,如:
const arr=[1,2,3,4];const [first,second]=arr;
; - 函数的对象参数:使用解构赋值,如:
const person={name:'lili',age:12}; function sayHi({name,age}){ ...};
;
- 数组成员变量:使用数组成员变量时,优先使用解构赋值,如:
- 4》对象
- 对象尽量静态化:对象一旦定义就不得随意添加新的属性;
- 对象动态属性采用属性表达式;
- 对象的属性采用简洁表达式;
- 单行定义的对象,最后一个属性后不以逗号结尾;
- 多行定义的对象,最后一个属性以逗号结尾;
// ① 动态属性表达式 const obj={id:2, name:'San FranciSco', [getKey('eabled')]:true } // ②简洁表达式 let ref='it is a string'; const atom={ref, value:1, addValue(value){ return atom.value+value }; // ③单行定义对象 let obj={k1:k1,k2:k2:k3:k3}; // ④多行定义对象 let obj2={ k1:'k1', k2:'k2', k3:'k3', } ```
- 5》数组
- 复制数组:使用扩展运算符
...
; - 类数组转换成数组:使用
Array.from()
;// 复制:数组==>数组 let itemsCopy=[...Array1]; // 转换:类数组==>数组 let foo=document.querySelectorAll('.foo'); let nodes=Array.from(foo);
- 复制数组:使用扩展运算符
- 6》函数:
- 采用箭头函数:①箭头函数更简洁;②箭头函数默认绑定
this
,可取代Function.prototype.bind
功能; - 使用默认值语法设置函数默认值;
- 函数参数所有配置项集中在最后一个对象,布尔值不可直接作为参数;
- 使用rest运算符
...
替换arguments
变量;// ①箭头函数取代 function.prototype.bind let boundMethod=(...prams)=>method.apply(this,params); // ②布尔参数:不能直接作为默认参数、可放在最后一个对象 function (a,b,{option:false}={}){//....}
- 采用箭头函数:①箭头函数更简洁;②箭头函数默认绑定
- 7》Map结构:区分Object和Map
- 模拟实体对象使用
Object
; - 只需要
key:value
的数据结构使用Map
:Map內建有便利机制;
- 模拟实体对象使用
- 8》Calss类
- 采用类Class取代需要propertype的操作:class的语法更简洁;
- 采用
extends
实现继承:extend语法更简洁,且不存在破坏instance运算的危险;// ① 采用 Class取代property操作 // 使用原型方法propertype function Queue(arr=[]){ this._queue=[...arr]; } Queue.propertype.pop=function(){ let item=this._queue[0]; this._queue.splice(0,1); return item; } //使用类 class实现 class Queue{ constructor(arr=[]){ this._queue=[...arr]; } pop(){ let item=this._queue[0]; this._queue.splice(0,1); return item; } } // ②使用extends实现继承 // 采用instance算法 function PeekableQueue(contents){ Queue.apply(this,contents); } inherits(PeekableQueue,Queue); PeekableQueue.prototype.peek=function(){ return this._queue[0]; } // 采用extends语法实现继承 class PeekableQueue extends Queue{ peek(){ return this._queue[0]; } }
- 9》模块
-
使用
import
语法替代require
语法:Module语法是JavaScript模块的标准语法; -
使用
export
语法取代nodule.exports
语法:module.exports是CommonJs语法; -
模块输出的函数,函数名采用驼峰命名法;
-
模块输出的对象,对象名首字母大写;
-
单个输出值采用
export default
语法; -
多个输出值采用
export {obj1,obj2}
:不可同时使用多个export default
、不可用export default
与普通export
共用;// ①一个模块输出多个模块 import { fn1,fn2} from 'ModuleA'; // ② export取代module.exports语法 let Person={}; module.exports=Person; // CommonJS语法 export default Person; // JavaScript语法 // ③输出函数 function makeStyleGuide(){}; export default makeStleGuide; // ④输出类、对象 let StyleGuid={es6:{test:'',include:''}}; export default StyleGuid;
-
2.常用代码检测工具
PS:各大公司风格规范链接jscs.info