在工作中,制定一套统一的编码风格,可以提高开发效率,维护起来的也要容易很多,也能避免一些不必要的错误出现。

项目中常用的检查编码风格的工具JSLintJSHintJSCSESLint,,在这呢,我就不介绍这些工具的使用,大家可以自行去看看官方文档就好,我就给大家介绍平时写时候的要点就好

基本的格式化

缩进层级

使用制表符进行缩进(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代码的更多相关文章

  1. 前端小白想要编写可维护的js

    我是一名前端小白,之前没写过多少代码,心里没有代码质量这个概念,人人都说代码是团队的产物,应该将代码写规范,但是我对具体什么样的代码是可维护的是茫然的. 我没写过多少代码,本来好多东西就不咋会,每次给 ...

  2. 编写可维护的JavaScript代码(部分)

    平时使用的时VS来进行代码的书写,VS会自动的将代码格式化,所有写了这么久的JS代码,也没有注意到这些点.看了<编写可维护的javascript代码>之后,做了些笔记. var resul ...

  3. 一步步教你编写不可维护的 PHP 代码

    译者注:这是一篇很棒文章,使用有趣的叙述方式,从反面讲解了作为一个优秀的 PHP 工程师,有哪些事情是你不能做的.请注意哦,此篇文章罗列的行为,都是你要尽量避免的. 随着失业率越来越高,很多人意识到保 ...

  4. 如何编写高质量的js代码--底层原理

    转自: 如何编写高质量的 JS 函数(1) -- 敲山震虎篇   本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/7lCK9cHmunvYlbm ...

  5. 用Flow编写更好的js代码

    关于本文: 原文地址 翻译地址 译者:野草 本文发表于前端早读课[第897期] 你是否经常在debug那些简单可避免的bug?可能你给函数传参的时候搞错了参数的顺序,或者本来应该传个Number类型的 ...

  6. 编写可维护的javascript代码--- 2015.11.22(注释)

    1.单行注释 // 这是一句单行注释 2.多行注释 /* 这里是代码 */     /*  这里都是注释 1232132  */      java的注释风格 /* * 另一段注释 * 这段注释包含2 ...

  7. 编写可维护的JS 01

    1.编程风格 缩进层级 使用制表符进行缩进 2个/4个空格缩进 语句结尾 不省略分号 行的长度 不超过80个字符 换行 在运算符后面换行 空行 在以下场景中添加: 方法之间 在方法中局部变量与第一条语 ...

  8. 编写可维护的javascript代码--- 2015.11.21(基本格式化)

    1.1 每行的编码需要控制在80字符. 1.2 改用:的地方必须用上. 1.3 缩进用2个制表符,不过4个也可以. 1.4 当代码一行显示不全需要折行显示,这里我暂且假定缩进为4个字符. 1.5 如果 ...

  9. 编写可维护的javascript代码---开篇(介绍自动报错的插件)

    文章开篇主要推荐了2款检测编程风格的工具: JSLint和JSHint: jsLint是由Douglas Crockford创建的.这是一个通用的javascript代码质量检测工具,最开始JSLin ...

随机推荐

  1. Sprint--5.21

    看到作业要求组长就召开小组成员开了一个简短的会议,会议内容大致是这样的: 1.再次明确任务:就是每一个人都要清楚知道自己扮演的角色应该做些什么,怎么去做: 2.组长定时更新博客,每一位小组成员也要写进 ...

  2. 小学四则运算结对项目报告(GUI)

    小学四则运算结对项目报告(GUI) 一.Coding.Net项目地址: https://git.coding.net/wsshr/Calculation.git 二.PSP表格(完成前): PSP 任 ...

  3. TCP系列54—拥塞控制—17、AQM及ECN

    一.概述 ECN的相关内容是在RFC3168中定义的,这里我简单描述一下RFC3168涉及的主要内容. 1.AQM和RED 目前TCP中多数的拥塞控制算法都是通过缓慢增加拥塞窗口直到检测到丢包来进行慢 ...

  4. Centos7 Zookeeper 集群安装

    1:安装java 环境 -openjdk* 2:zookeeper 安装 (官网 http://www.apache.org/dyn/closer.cgi/zookeeper/) 2.1 目录创建 自 ...

  5. jquery 点击弹出层自身以外的任意位置,关闭弹出层

    <!--弹出层---> <div class="mask">    <div class="wrap"></div&g ...

  6. 操作系统 cmd mini OS

    #include <stdio.h>#include <stdlib.h>#include <string.h> void word(char *a){ if(st ...

  7. cxDBVerticalGrid

    定位在第一行并显示内置编辑器 cxDBVerticalGrid1.FocusedRow := cxDBVerticalGrid1.Rows[0]; cxDBVerticalGrid1.ShowEdit ...

  8. MYSQL中可以实现类似IF判断的方法

    MYSQL中可以实现类似IF判断的方法 新建一张客户表,如下:sex:1-男,2-女,3-未知:level是客户的级别:1-超级VIP客户,2-VIP客户,3-普通客户 方式一:case函数:流程控制 ...

  9. Longest Increasing Subsequence的两种解法

    问题描述: 给出一个未排序队列nums,如[10, 9, 2, 5, 3, 7, 101, 18].找出其中最长的增长序列,但不是连续增长序列,如[2, 3, 7, 101]就是对应的最长增长序列LI ...

  10. 在Asp.Net Core中使用Session

    1.在Stratup.cs中配置Session public void ConfigureServices(IServiceCollection services) { services.AddSes ...