为什么要做这个?市面上的前端开发规范很多,有的过于陈旧,有的过于简单片面。目前,这些问题已经编制了一个最新最完整的前端开发规范,包括JS、CSS、HTML、lint、Vue等,这样做的目的是为了提高代码的可读性和可维护性。统计表明,在一个大中型项目中,代码的后期维护成本远高于开发成本。因此,提高代码的可维护性,大大降低了项目的维护成本。实现项目开发的标准化。目前的项目研发过程类似于汽车等工业产品的流水线生产模式。通过规范的制定,可以促进研发的标准化。减少错误并促进代码审查。在艺术的世界里,我们提倡无拘无束的风格,但在代码的世界里,我们必须提倡开发规范,这样会减少bug的数量,减少问题排查的时间。JS篇1.代码风格1.1.编码格式JavaScript文件使用无BOM的UTF-8编码。ps:UTF-8编码具有更广泛的适应性。在使用程序或工具处理文件时,BOM可能会造成不必要的干扰。1.2.代码缩进使用2个空格。缩进1.3。代码空间1.3.1。二元运算符两边各有一个空格。一元运算符和操作数之间不允许有空格//badleta=12a=b+ca++//goodleta=14a=b+ca++1.3.2,左花括号前有一个空格{at代码块的开头。//badif(condition){}while(condition){}functionfuncName(){}//goodif(condition){}while(condition){}functionfuncName(){}1.3.3,if/else/for/while/function/switch/do/try/catch/finally关键字后,有一个空格。//badif(condition){}while(condition){}//goodif(condition){}while(condition){}1.3.4、创建对象时,属性中的:后面有一个空格,和之前不允许:有空格。//badvarobj={a:1,b:2,c:3}//goodvarobj={a:1,b:2,c:3}#####1.3.5、函数声明、命名函数在表达式和函数调用中,函数名和(.//badfunctionfuncName(){constfunc=function(){}funcName()//goodfunctionfuncName(){}constfuncName=funcName(){}之间不允许有空格}funcName()2.变量声明2.1、const、let、var所有变量尽量使用constlet,尽量不要使用var。ps:这样做可以保证不能重新赋值引用,避免出错和代码看不懂。另外,把所有的const和let分组。如果不写关键字,变量会暴露在全局上下文中,很可能会和已有的变量冲突。另外,也很难知道变量的作用域是什么。//badvara=1//goodconsta=1constb=2letc=3letd=42.2,Reservedwords使用保留字作为对象的键值,所以在IE8下不会运行//badconsta={default:{},//定义ault是保留字common:{}}//goodconsta={defaults:{},common:{}}2.3、引号对字符串使用单引号,尽量不要使用双引号。ps:因为大部分时候我们的字符串。特别是在html中会出现双引号//badconsta="123"//goodconsta='123'2.4、分号问题以下几种情况可以声明变量末尾不用分号,import,export,return,throw,breakps:没有分号简洁明了,根据ASI[AutomaticSemicolonInsertion]机制,解析时会自动插入分号//badleta=12;importxxxfrom'aa';return;thrownew错误(错误);中断;//goodleta=12importxxxfrom'aa'returnthrownewError(err)break2.5,链式赋值变量不进行链式赋值,变量链式赋值会创建隐藏的全局变量//badleta=b=2//goodleta=2让b=22.6。冗余变量中不允许使用未使用的变量。声明但未使用的变量通常是重构不完整造成的错误。这样的变量在代码中浪费空间,给读者带来困扰3.创建变量3.1.创建对象变量,请使用字面值创建ps:代码少,可读性高,运行速度快//badconsta=newObject()constb=newArray()//goodconsta={}constb=[]3.2、创建函数不要使用Function构造函数创建函数ps:代码少,可读性高,运行速度快//badconstadd=newFunction('a','b','returna+b')//goodconstfunc1=function(){}3.3.创建字符串变量字符串过长时,建议不要使用字符串连接符换行\,而是使用+//badconststring='GoodFuture\isaverygoodeducationalcompany\真的很好'//goodconststr='GoodFuture'+'是一家很好的教育公司'+'真的很不错'程序生成的字符串,建议使用模板字符串consttest='test'//badconststr='a'+'b'+测试//goodconststr=`ab${test}`4.箭头函数4.1.当你必须使用函数表达式(比如传递匿名函数)时,使用箭头函数来标记ps:它将创建一个在此上下文中执行的函数版本,通常是你想要的,并且具有更清晰的语法//bad[1,2,3].map(function(x){consty=x+1returnx*y})//好[1,2,3].map(x=>{consty=x+1返回x*y})4.2。箭头函数中参数的括号。如果箭头函数只有一个参数,则不加括号。介绍很清楚//bad[1,2,3].map((x)=>{consty=x+1returnx*y})//good[1,2,3].map(x=>{consty=x+1returnx*y})4.3.如果函数体只包含返回无副作用表达式的语句,则可以省略花括号并使用隐式返回,否则保留花括号并使用返回语句//bad[1,2,3].map(number=>{constnextNumber=number+1`Astringcontainingthe${nextNumber}`})//good[1,2,3].map(number=>`Astringcontainingthe${number}`)5.解构赋值ps:解构可以避免创建对属性的临时引用5.1。对象解构当你需要使用一个对象的多个属性时,请使用解构赋值//badfunctiongetFullName(user){constfirstName=user.firstNameconstlastName=user.lastNamereturn`${firstName}${lastName}`}//goodfunctiongetFullName({firstName,lastName}){return`${firstName}${lastName}`}多个数组对于值,也请使用解构赋值constarr=[1,2,3,4]//badconstfirst=arr[0]constsecond=arr[1]//goodconst[first,second]=arr5.3,function当返回参数的解构函数需要返回多个值时,请使用对象的解构,而不是数组的解构ps:这样可以随时无损地添加或更改属性的顺序//badfunctiondoSomething(){return[top,right,bottom,left]}//如果是数组解构,那么调用的时候需要考虑数据的顺序const[top,xx,xxx,left]=doSomething()//goodfunctiondoSomething(){return{top,right,bottom,left}}//这个时候不需要考虑数据的顺序const{top,left}=doSomething()5.4,默认解构的值在解构变量的时候加上默认值,防止读到空值orundefined//badconst{a,b}={a:3}//goodconst{a=10,b=1}={a:3}6.类和构造函数6.1.使用class避免直接操作prototypeps:容易造成全局污染导致冲突,定位bug不易定位。//badfunctionQueue(contents=[]){this._queue=[..contents]}Queue.prototype.pop=function(){constvalue=this._queue[0]this._queue.splice(0,1)返回值}//goodclassQueue{constructor(contents=[]){this._queue=[...contents]}pop(){constvalue=this._queue[0]this._queue.splice(0,1)返回值}}6.2。使用extends实现继承ps优点:清晰,方便,这是一种内置的实现原型继承的方式,不破坏instanceof//badconstinherits=require('inherits')functionPeekableQueue(contents){Queue.apply(this,contents)}inherits(PeekableQueue,Queue)PeekableQueue.prototype.peek=function(){returnthis.queue[0]}//goodclassPeekableQueueextendsQueue{peek(){returnthis.queue[0]}}7.对象属性7.1。优先使用.访问对象属性ps:优点是简单方便constjoke={name:'haha',age:28}//badconstname=joke['name']//goodconstname=joke.name7.2,[]constluke={jedi:true,age:28,12:'num'}functiongetProp(prop){returnluke[prop]}constisJedi复制代码=getProp('jedi')8、条件运算8.1、使用===和!==代替==和!=constname='test'//badif(name=='test'){//...}//goodif(name==='test'){//...}8.2.尽量使用简洁的表达式constname=''//badif(name===''){//......}//goodif(!name){//......}8.3.如果函数或全局的else块后面没有语句,可以删除else//badfunctiongetName(){if(name){returnname;}else{返回'未命名';}}//goodfunctiongetName(){if(name){返回名称;}return'unnamed';}9.eval()方法是evil的,所以我们协议禁止使用这个方法ps:eval会引起XSS攻击;eval会干扰作用域链等,不建议在代码中使用eval10、不要修改内置对象的原型11、变量命名规则11.1、常规变量使用小驼峰格式letuserInfo={}11.2,全局常量使用大写字母,多个字母用下划线连接constMATH_PI=3.1411.3,类中私有变量以下划线开头11.4,类名采用大驼峰格式classUserInfo{}11.5,普通函数名称使用小型驼峰式函数getUserInfo(){}11.6。对枚举变量使用大驼峰式大小写。枚举属性全部使用大写字母,单词之间使用下划线分隔。constWeek={星期一:0,星期二:1}11.7。boolean类型的变量建议以is或has开头[建议]//通用变量constloginStatus=0//全局常量constCOUNT=0//全局常量constMAX_NUM=99//类声明classPoint{constructor(name,age){this._name=namethis._age=age}toString(){return'('+this._name+','+this._age+')'}}//普通函数functionstringFormat(source){}//枚举变量constTargetState={READING:1,READED:2,APPLIED:3}//布尔类型变量constisReady=falseconsthasSelected=false12,&&and||binaryBooleanoperatorsareShort-circuitable,lastitemwillonlycalculatedinnecessary//a++willnotbeexecutedletx=falseleta=1lety=x&&a++13,commentspecification13.1,单行注释占用asingleline,//后跟一个空格,缩进以匹配被注释掉的下一行代码。13.2.多行注释尽量避免使用像/*.../这样的多行注释。当有多行注释内容时,使用多个单行注释。13.3.文档注解格式使用@keydesc格式写常用关键字:@author作者@param参数@example示例@link链接@namespace命名空间@requires依赖模块@return返回值@version版本号param类型定义以{开头并以}结尾。常用的param类型:{String},{Number},{Boolean},{Object},{Function},{RegExp},{Array},{Date}13.4,Function/method注解包括对函数的描述。当有参数和返回值时,必须用注解/***@desc函数描述*@param{String}p1参数1的描述*@param{String}p2参数2的描述*@param{Number=}p3参数3说明(可选)*@return{Object}返回值说明*/functionfoo(p1,p2,p3){return{p1:p1,p2:p2,p3:p3}}
