领导一看就加薪的编程风格!!!——读书笔记篇《编写可维护的js》(一)

在公司中,我们不得不去与各种各样的人合作,于是每个人必须思考自己如何在团队环境中生存下来。本文是阅读了《编写可维护的javascript》之后总结了一些干货。谈不上自己的看法,本文只能算得上阅读本书的一些实践与总结。其实在之前的实习公司里就有一套自己的编程规范,个人感觉还是吃到了一些甜头,于是总结一下,准备用于日后的开发。在这本书中,他收集了很多关于编程规范的讨论,比如有jquery核心风格指南、goolge的javascript风格指南、sproutCore风格指南、dauglas Crockford的javascript代码规范等。有些风格没有好坏,只是习惯问题。但是总要有一套规范来约束开发者,提高合作的效率,毕竟我们绝大多数之间都在维护和阅读别人的代码,这是每段代码的宿命。它写出来就是为了给人看的,而不是为了运行。

程序是写给人读的,只是偶尔让计算机执行一下。 —— Donald knuth.

编程风格

在团队开发中,所有的代码看起来风格一致是非常重要的。这大大节省了开发者阅读理解一段代码的时间。如果项目庞大又是初次接触,一段没有风格和规范的代码真的很让人头疼。没有注释,没有缩进,没有好的命名规范,等等这都让我们感到非常的无可奈何。编程风格是个人的事情,但是只有放到团队开发中才能发挥其作用。

基本的格式化

代码缩进

恰当的使用缩进,统一缩进风格节省阅读时间。在缩进风格上,有两种主张:

  • 制表符缩进
    优:制表符与缩进层级之间有一对一的关系。 可配置制表符长度。
    劣:系统对制表符的理解不一致。不同系统打开可能不同,无法满足预期。
  • 空格缩进
    优:文件的展现格式没有差异
    劣:代码格式化的方式非常原始

这两种没有绝对的用哪一种更好,完全看个人和团队风格。不过建议后者。因为缩进的本意就是为了团队更好的阅读和理解,如果团队拿到代码时缩进出现了混乱,失去了缩进的意义。

//有缩进     推荐  
if(){
    if(){
        alert(1);
        alert(2);
    }else{
    	alert(3);
    	if(){
			alert(4);
		}
    }
}else{
    alert(5);
}

//无缩进或缩进混乱 不推荐
if(){
if(){
        alert(1);
    alert(2);
}else{
    alert(3);
if(){
			alert(4);
		}
}
}else{
alert(5);
} 

很多人说写代码的不会故意这样写,每个人有自己的风格。但是一段代码被多个人修改,不同的人有不同的风格,最后呈现这样一段代码是完全有可能的。这也体现了团队统一编程风格的好处。

结尾分号

这一点之所以能够拿出来说,是因为js语言有赖于自动插入分号(ASI)机制。ASI会自动的寻找代码中应当使用分号的地方加上。如果开发者习惯性不加结尾的分号,多数情况下没有问题,但是ASI机制能否时时刻刻保证分号插入与开发者表达意义完全一致。答案是不能的。首先自动插入分号的规则复杂,开发者很难逐一理解并牢记于心。其次,几乎没有人刻意的去学习这样一套法则。他的成本比我们习惯加上分号要高的多。所以虽然加上分号与不加分号在js里都是合法的,并且我们并不否认ASI机制本身在很多场景下是非常有用的,可以帮助我们减少代码的错误,只是当我们认为不需要加上分号而ASI认为需要时,或者我们认为需要要单是ASI认为不需要时就会引发x问题。我们推荐加上分号。

//常见的bug
function getobj1(){
	return     //此行分析器会理解成 return;ASI自动在return后加上了分号,所以什么都没返回。因此引发bug
	{
		a:'12',
		b:'34'
	}
}

//修复
function getobj2(){
	return {
		a:'12',
		b:'34'
	}
}

//但是我们依然推荐加上分号
function getobj2(){
	return {
		a:'12',
		b:'34'
	};
}
行长与换行
  • 行的长度:按照其他的一些规范,个人建议行最大长度尽量控制在80-100之间。
  • 换行:当行的长度达到上限,为了增加阅读体验,就需要换行。换行也是有门道和方法的。一般情况下我们会在运算符之后换行,且两个缩进或者赋值语句与等号后首个字符对齐。第一点是为了防止ASI机制自动加上分号,避免错误。第二点是与另起一行的代码区分开来。
//推荐方式

if(isAksjdfn && isAsdsjdfn && isAksddfn && isAksjasddfn && isAkfasjdfn &&  //此处在运算符&&后换行
		isAksdfjdfn  ){    //此处缩进2次 8空格
	isisAksjdfn = false;    //此处缩进一次 4空格
}

setData(isAksjdfn,isAsdsjdfn,isAksddfn,isAksjasddfn,isAksddfn,    //此处在运算符,后换行
		isAksjasddfn);    //此处缩进2次 8空格
		
let result = string1 + string1 + string1 + string1 + string1 + string1 +     //此处在运算符+后换行
			 string1 + string1 + string1 ;    //此处缩进至赋值运算符之后对齐,确保代码可读性。


//不推荐代码风格
if(isAksjdfn && isAsdsjdfn && isAksddfn && isAksjasddfn && isAkfasjdfn    //不推荐此处在运算符&&前换行
	&& isAksdfjdfn  ){    //不推荐,此处缩进1次 4空格
	isisAksjdfn = false;    //此处缩进一次 4空格
}

setData(isAksjdfn,isAsdsjdfn,isAksddfn,isAksjasddfn,isAksddfn //不推荐此处在运算符,前换行
,isAksjasddfn);    //不推荐,无缩进
		
let result = string1 + string1 + string1 + string1 + string1 + string1 +  
	 string1 + string1 + string1 ;    //不推荐,此处缩进未与赋值运算符之后对齐


空行

空行这个风格一般没人去注意,但是空行也是有学问的。通常来讲一大段的逻辑,如果全部写在一起,可读性会受影响。我们相对而言更喜欢具有段落层次的代码,这个段落层次主要靠空行视觉分割来实现。
一般来说以下几点加上空格可读性会更好:

  • 流程控制语句之前(for if while 等)
  • 单行或多行注释之前
  • 两个相邻的方法之间
  • 初始化变量和第一条逻辑之间
  • 不同逻辑块之间
命名规则

在程序中我们最无法避免的就是变量和函数,因此变量和函数的命名可读性也非常重要。

Javascript语言的核心ECMAScript就是遵循了驼峰命名法。所谓的驼峰命名就是由小写字母开始,后续每个单词都首字母大写。但其实两千年左右,js还流行另一种命名法,叫匈牙利命名法。这种方法是名字之前冠有类型标识符前缀。

命名一般在简短和可读两者之间取得一个平衡。
简短即字面意思
可读就是见名知意

变量和函数命名

变量要有变量的样子,函数要有函数的样子。

通常来讲,变量命名前缀应该为名词,可以一眼看出类型最好。
而函数名称前缀应该为动词,可以一眼看出函数的功能最好。

//推荐
var count = 10;
var resultData = {}; 
var name = 'zhangsan';
function getData(){}
function setData(){}
function isEmpty(){}
function haspro(){}

//不推荐系列
var count ;
var resultData; 
function theData(){}

常量命名

在ES6之前,没有变量与常量之分。这是因为ES6才引入了const标识常量。
一般情况下,按照C语言的约定,用全大写单词和下划线组合而成。

const MAX_LENGTH     //推荐
直接量
字符串直接量

字符串直接量需要注意两点,一点是嵌套引号始终使用一种风格,(要么单引号套包裹双引号,要么双引号包裹单引号,采用一种模式),另一点是多行字符串尽量使用连接符连接,很多规范已经明确说明禁止使用反斜杠。

//重点:从头到尾保持一种风格
var str1 = 'say "hi"';     //合法推荐
var str2 = "say'hi'";      //合法推荐
var str3 = "say\"hi\"";     //合法不推荐

//换行
var longStr = "kjsdfh kajsdf kagdfajt atfeyb \
ajhfag ";    //合法不推荐
var longStr = "kjsdfh kajsdf kagdfajt atfeyb " +
"ajhfag ";    //合法推荐
数字直接量

js中所有的数字类型都是一种存储方式IEEE754浮点数存储。在一部分需要注意的是:

  • 不要省略整数或小数部分(如果省略无法判断是漏写还是故意为之)
  • 不采用八进制。(八进制以0开头,容易引发歧义。010 是 8 还是10 呢?)
null和undefined

null的使用场景

  • 初始化一个可能赋值为对象的变量
  • 和已经初始化的变量比较,该变量可以是对象也可不是
  • 当函数参数或返回值期望是对象时,用作参数或者返回值。

//使用场景
var person = null;     //初始化一个可能赋值为对象的变量

function getPer(){
per = person;
if(per !== null){     //和已经初始化的变量比较,该变量可以是对象也可不是
	return other;
}else{
	return null;    //当函数参数或返回值期望是对象时,用作参数或者返回值。
}
}

不能使用null的场景:

  • 不要用null检测是否传入了参数
  • 不要用null检测未初始化的变量

//不应使用的场景
function getPer(arg1,arg2){
var per;
if(per !== null){    //,不推荐,不要用null检测未初始化的变量
	return other;
}else if(arg1 == null){    //不推荐 不要用null检测是否传入了参数
	return null;
}

最好的理解null的方法是把null当做对象的占位符。

undefined的使用
undefined在使用过程中应该注意到一点,声明过但未初始化的变量和从未声明的变量用typeof检测都是undefined。

var per;
typeof per;    //undefined per声明过但未初始化
typeof foo;    //undefined foo从未声明

因此我们一般情况下,如果使用一个可能被赋值为对象的变量,初始化null。尽量不要使用undefined特殊值。

对象和数组直接量
//推荐 简洁
var arr = [1,2,3];
var per = {name:"zhangsan",age:12};

//不推荐 繁琐
var arr = new Array(1,2,3);
var per = new Object();
per.name = "zhangsan";
per.age = 12;

注释

注释是代码中最常见的组成部分,是另一种形式的文档。注释一般用在什么地方呢?注释的目的是为了让代码更清晰。可以一眼理解的代码不必注释,如简单初始化。

一般难于理解的代码加注释
可能被认为错误的特殊处理代码加注释
浏览器hack加注释

单行注释

两个斜杠开始,行末结束。有三种使用情况:
1.注释单独一行,用于下一行或者下一部分代码解释,与下一行代码缩进相同,上一行需空行,体现段落层次
2.尾部注释,注释前应有一个缩进,字数符合要求,不超过行长度
3.批量缩进,代码编辑器自带


//参数合法性检查,此处注释用于下一行代码解释,与下一行代码缩进相同,上一行空行
if(!args){
	return ;    //尾部注释前应有一个缩进,字数符合要求,不超过行长度
}


//if(!args){
//	return ;    
//}
//批量注释
多行注释

/*开始,以*/结束。用于描述一段代码,与这段代码缩进相同,之前应有一个空行。

if(!args1){
	return ;   
}

/*
 *参数合法性检查
 *此处注释用于下一行代码解释
 *与下一行代码缩进相同
 *上一行空行
 *这是Java的习惯,其实这只要是/ *开始* /结束就可以,不论中间怎么写都OK
 */
if(!args2){
	return ;    
}

文档注释

/**开始,**/结束,多用于解释一个文档或者函数的信息

/**
@method:getName
@describe: 根据身份证号获取姓名
@params: cardId string类型的ID
@return: name string类型的name
@author: syt@ajdf.com
@date: 2020-07-01 11:11:11
@lastmodified:2020-07-02 11:11:11
@adc:这些都可以根据需要自由搭配,对应配置就好
**/
function getName(cardId){
	return "zhangsan"
}

语句和表达式

花括号与间隔

注意点:
1.条件判断时左边花括号不要移到下一行,避免浏览器自动加分号导致问题
2.if语句或者for等代码块之前空一行,增强层次感,便于阅读
3.左右括号内侧各一个空格 自我推荐


function getName(cardId){    //此处花括号不要移到下一行,避免浏览器自动加分号导致问题
	
	if(){    //if语句或者for等代码块之前空一行,增强层次感,便于阅读
		return "lisi";
	}else if( cardId ){   
		return "wangsu";    //缩进一致
	}else{
		doSomething;
	}

	//括号也有风格的,但是个人觉得风格只要统一就好,没有其他大的影响
	if(ID){
		//方式1:没有空格
	}
	if( ID ){
		//方式2:内侧各一个空格 自我推荐
	}
	if ( ID ) {
		//左右括号内外侧均有一个空格
	}
	
	return '';
}
switch与for
switch语句推荐风格:

1.case相对switch缩进一个层级
2.case语句上下空行
3.每条语句加上break,如有逻辑需要依次执行省略break,加上备注
4.永远加上default或者备注没有default

for语句注意事项:

1.传统的for循环一般用于遍历数组。
2.for循环中尽量少使用continue ,break等跳出循环的语句,如果可以用if模拟最好。这么做的目的是代码容易理解且不易出错。
3.for-in循环常用于遍历对象,不用来遍历数组。一般用hasOwnProperty方法过滤掉原型链上的属性。

变量函数和运算符

变量与函数的声明

由于js有声明提前的策略,这意味着我们在各个地方生命的变量在js解析时都会被提前到作用域的最前边。但这容易引发一个问题,就是我们在变量初始化之前很有可能已经调用了变量而产生了错误。例如:

var a = b + 5;
var b = 10;a
alert(a); //弹出框提示NAN

这里不会报错,因为js声明提前的机制,b会在使用之前先声明,赋值为undefined。因此执行b+5时其实是按照规则先把b转成了数字,即NAN,NAN+5还是NAN,下一步才赋值的b,因此打印出来NAN。

为了避免我们犯这样的错误,建议是把所有的初始化放在作用域的最前边。
另外函数的声明,函数的声明也遵循以上的提前策略。
函数声明时应当注意,不要在条件语句中声明函数,在不同的浏览器中执行结果不一样。应当尽可能的避免。目前只有在firfox中使用正常,但是我们应该尽可能避开这种js的灰色地带。

函数的调用

建议:为了与块级格式的风格相区分,一般情况下,我们调用函数时尽量写的紧凑,不要有空格。并且立即调用的函数整体加上括号,变于开发人员区分。

相等

js中是有强制类型转换的机制的,最常见的场景就是== 和!=这两个运算符。这种比较是非常微妙的。(后续分享)
一不留神就会造成很多错误。所以我们在比较时一般使用全等比较符进行比较,这种比较不会进行类型的转换。

到此为止呢,编程风格这一步分就给大家介绍完了。 如果想进一步的学习请看下文,这一篇主要介绍了在开发中我们应该以什么方式来编写代码,是的代码更不容易出错。也算是一些小的编程技巧,它不像上文中,主要强调代码的呈现方式。这篇文章主要强调代码的执行结果。 领导一看就加薪的编程风格!!!—— 读书笔记篇《编写可维护的js》(二)

下边真的可以不看 -----

想学习一些前端的书籍吗,我都帮你整理好啦!评论打出你想读的书,给你最全的笔记干货
超级全的前端知识,面试必备、系统复习必备哟哟哟

有想法评论提出哈,欢迎交流,小编也是渣渣一枚呢~一起进步呗

这次真的可以不看 -----

点个收藏呗,要不赞一个呗,小编手都敲累了,但还是持续加更呢~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值