编写可维护的js代码
在工作中,制定一套统一的编码风格,可以提高开发效率,维护起来的也要容易很多,也能避免一些不必要的错误出现。
项目中常用的检查编码风格的工具JSLint、JSHint、JSCS、ESLint,,在这呢,我就不介绍这些工具的使用,大家可以自行去看看官方文档就好,我就给大家介绍平时写时候的要点就好
基本的格式化
缩进层级
使用制表符进行缩进(tab键:一个制表符的长度相当于4个字符)
编辑器可以设置是一个缩进是2个空格还是4个空格还是8个空格,建议是使用4个空格,折中处理,很多编辑器默认也是4个空格.制表符和空格是两个概念,不要混淆
语句结尾
语句结尾用分号结尾,如果省略了分号的话,JSLint和JSHint默认都会有警告 注意点:(javascript Standard标准里面是可以不使用分号,加与不加就看你使用哪种标准)
// 合法的代码
function sayHello(){
console.log('hello world')
} // 合法的代码
function sayHello(){
console.log('hello world');
}
行的长度
一行代码不应该超过80个字符,超过80的话,就折行或隐藏
换行
当一行的长度达到了单行最大字符数限制是,就需要手动将一行拆成两行,通常我们会在运算符后换行,下一行会增加两个层级的缩进(两个tab缩进)
callFunction(document,element,windiw,"some string value",true,,
navigation);
注意点:主体部分的话,还是保留一个层级的缩进(一个tab,4个字符) 例外:当个变量赋值时,第二行的位置应当和赋值运算符的位置保持对齐
var result=something + anotherthing + yetAnohterthing + somethingElse +
anotherthingElse
空行
添加空行是为了提高代码的可读性,以下情况可以添加空行
- 在方法之间
- 在方法中的局部变量和第一条语句之间
if(flag){
for(let i=;i<;i++){
let p =i; if(p=){
console.log(p);
}
}
}
- 在多行或则单行注释之前
- 在方法内的逻辑片段之间
未完待续....
下面场景中应当使用null
- 用来初始化一个变量,该变量可能为一个对象
- 用来和一个已经初始化的变量比较该变量可以使也可以不是一个对象
- 当函数的返回值期望是对象时,用作返回值传出
下面场景不要用null
- 不要使用null来检测是否传入了某个参数
- 不要使用null来检测一个未初始化的变量
代码实例:
// 好的用法
var person=null;
// 好的用法
function getPerson(){
if(condition){
return new Person("Nicholas");
}
else{
return null
}
} // 好的用法
function getPerson(){
if(person!==null){
getMag();
} }
// 不好的写法:用来和初始化的变量比较
var person;
if(person!==null){
getMag();
} // 不好写法:检测是否传入了参数
function getArr(arg,agr2,agr3,agr4){
if(arg4!==null){
getMag();
}
}
undefined
undefined不全等于null null==undefined // true
null==undefined // false
typeof undefined // "undefined"
typeof null // object
注释
单行注释
- 独占一行的注释,用来解释下一行代码,折行注释之前总是有一行空行,切且缩进层级和下一行代码保持一致
- 在代码的尾部的注释,代码结束到注释之间要有至少一个缩进,注释(包括之前的代码部分)不应当超过单行最大字符数限制,如果超过了,就讲这条注释放置于当前代码行额上方
- 被注释掉的大段代码可以用单行注释,编辑器里面有自带
// 好的写法:留有空行,及正确的缩进
if(condition){ // 代码执行到这里,则表明通过了所有的安全性检查
allowed();
}
// 不好的写法:没有空行及错误的缩进
if(condition){
// 代码执行到这里,则表明通过了所有的安全性检查
allowed();
}
// 好的写法
var result=something +sometimes; // 是的就是这么写 // 不好的写法: 代码和注释之间没有间隔
var result=something +sometimes;// 是的就是这么写 // 好的写法:代码段使用单行注释
// if(condition){
// flag=true;
// allowed();
// } // 不好的写法:这里应该使用多行注释
// 集体那第五次
// 集体那第五次
// 集体那第五次
// 集体那第五次
// 集体那第五次
多行注释
建议的写法是:
/*
* 这是一段注释,风格是仿Java的
*/
- 多行注释注释和单行注释一样,前面都要留一行空行,且缩进层级和其描述的代码保持一致
if(condition){ /*
* 代码执行到这里,则表明通过了所有的安全性检查
*/
allowed();
}
文档注释
/**
这是一段说明文字
@method=merge
@param {object}
@return null
**/
第三章:语句和表达式
所有的语句块都应该使用花括号,包括:
- if
- for
- while
- do...while
- try..catch...finally
switch语句
缩进
switch (condition){
case "first":
break;
case "second":
break;
default:
// 代码
}
在JSLint中,是期望switch和case的层级缩进是一致的,如果不一致的话,就会警告,但是如果包含额外的空行的话,就不会报警告了
case语句的连续执行
可行方案:当你的代码中出现了case的连续执行,JSLint就会给出警告,但是如果你加上了一句注释的话,就能避免给出警告
switch (condition){ // 这里的连续执行没注释,会给出警告
case "fisrt";
case "second":
break; // 这里不会给出警告
case "third":
// 代码
// fall through
default:
// 代码
}
default
建议:当default中没有逻辑代码时,建议是可以省略default
for循环
尽量避免使用break,和continue语句
- break:退出循环
- continue:退出本次循环
for-in循环
for-in循环有个问题,就是它不仅遍历对象的实例属性,同样还遍历从原型继承来的属性,当遍历自定义对象的属性时,往往会因为意外的结果而终止,出于这个原因的考虑,最好使用hasOwnProperty()方法来为for-in循环过滤出实例属性
for (item in obj){
if(obj.hasOwnProperty(item)){
console.log("Property is "+item);
console.log("Property value is "+obj[item]);
}
}
对于循环没有使用hasOwnProperty()方法的for-in循环,JSlint会给出警告
变量函数运算符
相等:在判断相等的时候,为了规范,尽量用全等(=或则!)来判断,目的是为了防止强制转换
console.log(===""); // true 把字符串转为了数字来进行比较
原始包装类型:
原始包装类型有:String,Boolean,Number 3钟类型,他们都具有对象的特征,但是在工作中不建议使用
var name="milk";
name.author="coat";
console.log(name.author); // undefined
注意点:原始值本身是不具有对象特征,比如1.toString();是报错的必须这样做:var a=1;a.toString();
UI层的松耦合
将css中JavaScript中抽离
在js里面不应该直接操作样式表,而应该是操作className
// 原生写法
element.className+="reveal"; // h5中的写法
element.ClassList.add("reveal");
将JavaScript从html中抽离
把JavaScript代码写到外部的js文件中,这样的到时候修改就只需要修改一个文件就可以了
将html从JavaScript中抽离
从服务器加载
将模板放置在远程服务器,使用XMLHttpRequest对象来获取,但是该方法很容易造成XSS漏洞, 需要服务器对模板文件做适当的转义处理
简单的客户端模板
// 这段中%s是占位符
var li='<li><a href="%s"></a></li>'
var href="yes"
function sprintf(text){
var i=1;args=arguments;
return text.replace(/%s/g,function(){
return (i<args.length)?args[i++]:""
})
}
console.log(sprintf(li,"nihao"));
通常做法:将模板定义在html标签里面,并且注释掉模板文本,通过JavaScript的dom来提取
html部分:
<ul id="mylist">
<!-- <li id="item%s"><a href="/item%s"></a></li> -->
<li><a href="/item/2"></a></li>
<li><a href="/item/3"></a></li>
<li><a href="/item/4"></a></li>
</ul>
javascript部分:
var mylist=document.getElementById("mylist"),
templeText=mylist.childNodes[].nextSibling.data;
function sprintf(text){
let i=,args=arguments;
return text.replace(/%s/g,function(){
return (i<args.length) ? args[i++]:'';
})
}
function addItem(url,text){
var mylist=document.getElementById("mylist"),
templeText=mylist.childNodes[].nextSibling.data || "";
console.log(templeText);
result=sprintf(templeText,url,text);
}
// 这段中%s是占位符
var li='<li><a href="%s"></a></li>'
// console.log(sprintf(li,"我也是","是啊是啊","我的"));
addItem("/5","/five item");
检测
检测原始类型:
原始类型有:字符串,数字,布尔值,null,undefined
检测原始类型最好的方式是用typeof运算符
· 检测字符串 typeof 返回的是string
* 对于数字 返回的是 number
* 对于布尔值 返回的是布尔值
* 对于undefined 返回的是 undefined
* 对于null 返回的是 object
* NaN返回的是number
// 检测字符串
if(typeof name==="string"){
return true;
}
// 检测数字
if(typeof count==="number"){
return true;
}
// 检测布尔值
if(typeof flag==="boolean" &&flag){
return true;
}
// 检测undefined
if(typeof myApp==="undefined"){
return true;
}
检测引用类型
内置的引用类型有:Array,Object,Date和Error
检测最好是用instanceof来检测:语法
value instanceof construtor
检测的例子
// 检测日期
if(value instanceof Date){
console.log(value)
}
// 检测正则
if(value instanceof RegExp){
console.log(value)
}
instance还可以检测原型链
var now=new Date();
console.log(now instanceof Object); // true
console.log(now instanceof Date); // true
检测函数
函数检测最好用typeof
function Fuc(){}
console.log(typeof Fuc==="function"); // true
注意点:在IE8以及更早的版本中,typeof来检测dom节点,的函数,返回的都是object而不是function(93页中说明)
console.log(document.getElementById); //"object"
console.log(document.getElement); //"object"
console.log(document.getElementByTagName); //"object"
检测数组
检测数组的时候,用instanceof有时候并不一定准确,所以ES5中新增了一个isArray方法 说明:
var arr=[];
Array.isArray(arr); // true function isArray(value){
return Object.prototype.toString.call(value)==="[object Array]"
} // 如果是json对象的话,返回的则是[object,JSON]
检测属性
- in 运算符检测实例对象的某个属性是否存在
var obj={
count:0,
retlated:null
}
console.log("count" in obj);
- hasOwnProperty()方法 检测实例对象的某个属性是否存在:所有继承自Object的javascript对象都有这个方法,如果实力中存在这个属性则返回true(如果这个属性只存在原型中,则返回false),需要注意的是,在IE8以及更早的IE版本中,dom并非继承自Object,因此也不包含这个方法,,也就是说你在调用dom对象的hasOwnProperty()方法之前,应当检测其是否存在
// 对于所有非dom对象来说, 这是好的写法
if (object.hasOwnProperty('related')){
// 执行这里的代码
}
// 如果你不确定是否为dom对象,则这样写
if("hasOwnProperty" in Object&&object.hasOwnProperty('relative')){
// 执行这里的代码
}
编写可维护的js代码的更多相关文章
- 前端小白想要编写可维护的js
我是一名前端小白,之前没写过多少代码,心里没有代码质量这个概念,人人都说代码是团队的产物,应该将代码写规范,但是我对具体什么样的代码是可维护的是茫然的. 我没写过多少代码,本来好多东西就不咋会,每次给 ...
- 编写可维护的JavaScript代码(部分)
平时使用的时VS来进行代码的书写,VS会自动的将代码格式化,所有写了这么久的JS代码,也没有注意到这些点.看了<编写可维护的javascript代码>之后,做了些笔记. var resul ...
- 一步步教你编写不可维护的 PHP 代码
译者注:这是一篇很棒文章,使用有趣的叙述方式,从反面讲解了作为一个优秀的 PHP 工程师,有哪些事情是你不能做的.请注意哦,此篇文章罗列的行为,都是你要尽量避免的. 随着失业率越来越高,很多人意识到保 ...
- 如何编写高质量的js代码--底层原理
转自: 如何编写高质量的 JS 函数(1) -- 敲山震虎篇 本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/7lCK9cHmunvYlbm ...
- 用Flow编写更好的js代码
关于本文: 原文地址 翻译地址 译者:野草 本文发表于前端早读课[第897期] 你是否经常在debug那些简单可避免的bug?可能你给函数传参的时候搞错了参数的顺序,或者本来应该传个Number类型的 ...
- 编写可维护的javascript代码--- 2015.11.22(注释)
1.单行注释 // 这是一句单行注释 2.多行注释 /* 这里是代码 */ /* 这里都是注释 1232132 */ java的注释风格 /* * 另一段注释 * 这段注释包含2 ...
- 编写可维护的JS 01
1.编程风格 缩进层级 使用制表符进行缩进 2个/4个空格缩进 语句结尾 不省略分号 行的长度 不超过80个字符 换行 在运算符后面换行 空行 在以下场景中添加: 方法之间 在方法中局部变量与第一条语 ...
- 编写可维护的javascript代码--- 2015.11.21(基本格式化)
1.1 每行的编码需要控制在80字符. 1.2 改用:的地方必须用上. 1.3 缩进用2个制表符,不过4个也可以. 1.4 当代码一行显示不全需要折行显示,这里我暂且假定缩进为4个字符. 1.5 如果 ...
- 编写可维护的javascript代码---开篇(介绍自动报错的插件)
文章开篇主要推荐了2款检测编程风格的工具: JSLint和JSHint: jsLint是由Douglas Crockford创建的.这是一个通用的javascript代码质量检测工具,最开始JSLin ...
随机推荐
- Hibernate left join
6.4.5 左外连接 左外连接(Left Outer Join)查询出左表对应的复合条件的所有记录,如查询李晓梅同学的选课信息.下面是类HQLLeftOuterJoinQuery的源代码. 其实关联 ...
- quartusII13.0使用教程
1.新建工程项目,填写项目存储路径和工程名,不要出现中文路径 2.添加已存在文件(可选),在[File name]下选择已经存在的工程项目,利用[Add]或[Add all]命令添加文件到新工程,点击 ...
- Java实现小学四则运算练习
Github项目地址:https://github.com/feser-xuan/Arithmetic.git 1.需求分析 软件基本功能要求如下: 程序可接收一个输入参数n,然后随机产生n道加减乘 ...
- php aes加密
<?php namespace Aes; error_reporting(E_ALL); ini_set('display_errors', '1'); class Aes { /** * va ...
- chdir
<?php //获得当前目录 echo getcwd(); echo "<br />"; //改变为 images 目录 chdir("images&q ...
- Oracle与SQLSERVER 批处理执行 DDL 语句
1. 公司里面的 很多同名的数据库 的一个表都错误的多了一个列 要是每个都用数据库连接工具打开 感觉太废时间了. 比如写个sql命令来执行. 具体方法: Oracle 使用 sqlplus sqlpl ...
- poj 1144(割点)
题目链接:http://poj.org/problem?id=1144 题意:给出一个无向图,求关键节点的个数. 分析:双连通分量Tarjan算法直接求割点就行了,裸的模板题. AC代码: #incl ...
- Dubbo学习(二) Dubbo 集群容错模式-负载均衡模式
Dubbo是Alibaba开源的分布式服务框架,我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务应用场景来选择合适的集群容错模式,这个对于很多应用都是迫切希望的,只需要通过简单的配 ...
- Spring学习13-中IOC(工厂模式)和AOP(代理模式)的详细解释
我们是在使用Spring框架的过程中,其实就是为了使用IOC,依赖注入,和AOP,面向切面编程,这两个是Spring的灵魂. 主要用到的设计模式有工厂模式和代理模式. IOC是工厂模式参考:设计模式- ...
- UFLDL学习笔记 ---- 主成分分析与白化
主成分分析(PCA)是用来提升无监督特征学习速度的数据降维算法.看过下文大致可以知道,PCA本质是对角化协方差矩阵,目的是让维度之间的相关性最小(降噪),保留下来的维度能量最大(去冗余),PCA在图像 ...