编写可维护的JavaScript

软件生命周期中80%的成本都消耗在了维护上;而且几乎所有的维护者都不是代码的直接开发人。如何让自己写的代码让别人阅读起来更高效?当然是写代码的时候注入一些规范。那么在Javascript中有哪些编程风格值得我们去注重呢?这篇文章将总结《编写可维护的JavaScript》里面的观点。

缩进风格

上图是Stack Overflow的调查,可见,大部分的Programmer都喜欢用tab进行缩进。每行缩进由4个空格组成。

语句结尾

建议不要省略分号。很多人喜欢写js代码很依赖于自动分号插入,也就是语句后面不加分号。但是这是大多数的情况,像return这样的语句是会出错的。类似的还有其他一些语法,这里就不细说自动分号插入机制了,感兴趣的童鞋可以前往JavaScript ASI 机制详解

行的长度

这个之前在另外一篇博客中有介绍过,为了保证在小屏笔记本和大屏幕上看到的代码是一致的,通常建议每一行代码不要超过80列。

换行

代码长度超过80列,换行也是有讲究的。建议换行的代码增加两个缩进长度。例如:

callFunction(element1, element2, element3, element4,
        element5);
复制代码
空行

整个函数代码没有空行地紧凑在一起会给阅读代码的人一定的视觉疲劳。也让人厌倦,起码我看到这样的代码就不想再看下去了。对于空行地建议:

  • 在方法之间
  • 在方法中的局部变量和第一条语句之间
  • 在注释之前
  • 在方法内的逻辑片段之间插入空行,提高可读性
命名

命名是我觉得规范中最难的点,怎么让变量或者函数名称还有意境。结合不同的场景,设置不一样的名称。让维护代码的人像看小说一般地阅读代码,就说明命名是成功的!除了变量含义之外,其他的一些规范比如:

  • 驼峰写法
  • 变量用名词
  • 函数用动词+名词
  • 对象私有属性或方法前面加_
  • 常量用全部大写字母且分割单词用下划线
  • 构造函数首字母大写,且以非动词开头
注释

单行注释

  • 独占一行,用来解释下一行代码
if (condition) {
    
    // 如果代码执行到这里,代表通过了condition的校验
    next();
}
复制代码

注意注释之前要加空行、注释也要缩进。

  • 与代码同一行,用来解释之前的代码
var result = something + somethingElse;    // somethingElse will never be null
复制代码

注意注释与代码直接至少添加一个缩进。

  • 多行,用来注释掉一个代码块
// if (condition) {
//     doSomething();
//     doSomethingElse();
// }
复制代码

注释一个代码块时是在连续多行使用单行注释唯一可以接受的情况。但是最好别这样使用。

多行注释

if (condition) {

    /*
     * 如果代码执行到这里
     * 说明balabala
     */
     doSomething();
}
复制代码

要注意缩进、换行、空格、空行。

使用注释声明

注释说明,主要用来做记号。主要有以下几种:

  • TODO 说明代码还未完成,说明接下来要做的事情。
  • HACK 表明代码实现走了一个捷径。应当包含为何使用hack的原因。同时也表明也许会有更好的解决办法。
  • FIXME 说明代码存在bug,应当尽快修复。
  • REVIEW 说明代码任何可能的改动都需要评审。
变量、函数和运算符
  • 变量声明 变量声明习惯一般有两种:一种是“就近”原则,放在离使用最近的地方;第二种就是放在最上面,作为函数内的第一条语句。个人推荐后者,这跟JavaScript引擎解析代码的习惯是一致的。

  • 函数声明 函数声明也会被JS引擎提前,建议在函数调用之前声明函数。另外,推荐函数内部的局部函数应当紧接着变量声明之后声明。

  • 立即调用的函数 立即执行函数,在开发中肯定会经常使用。好的写法是:

var value = (function() {

    // 函数体
    return {
        message: 'Hi'
    };
}());
复制代码

清晰明了地的让人知道这是一个立即执行函数。

  • 严格模式 ES5引入了严格模式,通过这种方式解析执行js代码,来达到减少错误的目的。代码要以strict mode去解析也很简单,只要将use strict放到js代码中即可。当js解析器看到这样一条没有赋给变量的字符串之后,就会以严格模式去解析代码。一个原则:尽量少地影响到更多代码!什么意思呢?use strict可以放到任何位置,全局或者函数局部都可以。
// bad
"use strict";
function doSomething() {
    // 代码

}

// good
function doSomething() {
    "use strict";
    // 代码

}
复制代码

如果有多个函数要使用严格模式,就用立即函数限制起来,避免影响到全局。

(function() {
    "use strict";
    function doSomething() {
        // 代码
    }
    function doSomethingElse() {
        // 代码
    }
})();
复制代码
  • 相等 使用===、!==代替==、!=,避免类型转换。类型转换的相关内容这里就不说了,自行了解。
UI层的松耦合

松耦合的原则:修改一个组件时尽可能不需要修改其他组件代码。

  • 将JavaScript从CSS中抽离 避免使用CSS表达式

  • 将CSS从JavaScript中抽离 避免直接修改dom的样式,通过类名去实现想要的效果。

// bad
element.style.cssText = "color: red; left: 10px";

// good
.reveal {
    color: red;
    left: 10px;
}

element.className += " reveal";
复制代码
  • 将JavaScript从HTML中抽离 避免直接在HTML写事件处理程序和逻辑代码
事件处理

两个规则:

  • 隔离程序逻辑 将应用逻辑从所有事件处理程序中抽离出来是最佳实践,举个例子:
// bad
function handleClick(event) {
    var popup = document.getElementById("popup");
    popup.style.left = event.clientX + "px";
    popup.style.top = event.clientY + "px";
    popup.className = "reveal";
}

// good
function handleClick(event) {
    showPopup(event);
}

function showPopup(event) {
    popup.style.left = event.clientX + "px";
    popup.style.top = event.clientY + "px";
    popup.className = "reveal";
}
复制代码
  • 不要滥用事件对象 将事件对象event一直传递下去是个很烂的实践。别人并不知道你具体使用到事件对象的什么属性或者方法。继续用上面的例子:
// bad
function handleClick(event) {
    showPopup(event);
}

function showPopup(event) {
    popup.style.left = event.clientX + "px";
    popup.style.top = event.clientY + "px";
    popup.className = "reveal";
}

// good
function handleClick(event) {
    showPopup(event.clientX, event.clientY);
}

function showPopup(x, y) {
    popup.style.left = x + "px";
    popup.style.top = y + "px";
    popup.className = "reveal";
}
复制代码

vue的规范建议可以前往vue最佳实践,一起讨论学习吧!

编写维护JavaScript》向开发人员阐述了如何在团队开发中编写具备高可维护性的JavaScript代码,书中详细说明了作为团队一分子,应该怎么写JavaScript。本书内容涵盖了编码风格、编程技巧、自动化、测试等几方面,既包括具体风格和原则的介绍,也包括示例和技巧说明,最后还介绍了如何通过自动化的工具和方法来实现一致的编程风格。   《编写维护JavaScript》作者Nicholas C. Zakas是顶级的Web技术专家,也是《JavaScript高级程序设计》一书的作者。他曾是Yahoo!的首席前端开发工程师,在完成了从一名“独行侠”到“团队精英”的蜕变后,他站在前端工程师的角度提炼出众多的最佳编程实践,其中包括很多业内权威所推崇的最佳法则,而这些宝贵经验正是本书的核心内容。   《编写维护JavaScript》适合前端开发工程师、JavaScript程序员和学习JavaScript编程的读者阅读,也适合开发团队负责人、项目负责人阅读。运用本书中讲述的技巧和技术,可以使JavaScript团队编程从侠义的个人偏好的阴霾走出来,走向真正的高可维护性、高效能和高水准。 第一部分 编程风格 第1章 基本的格式化 1.1 缩进层级 1.2 语句结尾 1.3 行的长度 1.4 换行 1.5 空行 1.6 命名 1.6.1 变量和函数 1.6.2 常量 1.6.3 构造函数 1.7 直接量 1.7.1 字符串 1.7.2 数字 1.7.3 null 1.7.4 undefined 1.7.5 对象直接量 1.7.6 数组直接量 第2章 注释 2.1 单行注释 2.2 多行注释 2.3 使用注释 2.3.1 难于理解的代码 2.3.2 可能被误认为错误的代码 2.3.3 浏览器特性hack 2.4 文档注释 第3章 语句和表达式 3.1 花括号的对齐方式 3.2 块语句间隔 3.3 switch语句 3.3.1 缩进 3.3.2 case语句的“连续执行” 3.3.3 default 3.4 with语句 3.5 for循环 3.6 for-in循环 第4章 变量、函数和运算符 4.1 变量声明 4.2 函数声明 4.3 函数调用间隔 4.4 立即调用的函数 4.5 严格模式 4.6 相等 4.6.1 eval() 4.6.2 原始包装类型 第二部分 编程实践 第5章 UI层的松耦合 5.1 什么是松耦合 5.2 将JavaScript从CSS中抽离 5.3 将CSS从JavaScript中抽离 5.4 将JavaScript从HTML中抽离 5.5 将HTML从JavaScript中抽离 5.5.1 方法1:从服务器加载 5.5.2 方法2:简单客户端模板 5.5.3 方法3:复杂客户端模板 第6章 避免使用全局变量 6.1 全局变量带来的问题 6.1.1 命名冲突 6.1.2 代码的脆弱性 6.1.3 难以测试 6.2 意外的全局变量 避免意外的全局变量 6.3 单全局变量方式 6.3.1 命名空间 6.3.2 模块 6.4 零全局变量 第7章 事件处理 7.1 典型用法 7.2 规则1:隔离应用逻辑 7.3 规则2:不要分发事件对象 第8章 避免“空比较” 8.1 检测原始值 8.2 检测引用值 8.2.1 检测函数 8.2.2 检测数组 8.3 检测属性 第9章 将配置数据从代码中分离出来 9.1 什么是配置数据 9.2 抽离配置数据 9.3 保存配置数据 第10章 抛出自定义错误 10.1 错误的本质 10.2 在JavaScript中抛出错误 10.3 抛出错误的好处 10.4 何时抛出错误 10.5 try-catch语句 10.6 错误类型 第11章 不是你的对象不要动 11.1 什么是你的 11.2 原则 11.2.1 不覆盖方法 11.2.2 不新增方法 11.2.3 不删除方法 11.3 更好的途径 11.3.1 基于对象的继承 11.3.2 基于类型的继承 11.3.3 门面模式 11.4 关于Polyfill的注解 11.5 阻止修改 第12章 浏览器嗅探 12.1 User-Agent检测 12.2 特性检测 12.3 避免特性推断 12.4 避免浏览器推断 12.5 应当如何取舍 第三部分 自动化 第13章 文件和目录结构 13.1 最佳实践 13.2 基本结构 第14章 Ant 14.1 安装 14.2 配置文件 14.3 执行构建 14.4 目标操作的依赖 14.5 属性 14.6 Buildr项目 第15章 校验 15.1 查找文件 15.2 任务 15.3 增强的目标操作 15.4 其他方面的改进 15.5 Buildr任务 第16章 文件合并和加工 16.1 任务 16.2 行尾结束符 16.3 文件头和文件尾 16.4 加工文件 第17章 文件精简和压缩 17.1 文件精简 17.1.1 使用YUI Compressor精简代码 17.1.2 用Closure Compiler精简 17.1.3 使用UglifyJS精简 17.2 压缩 17.2.1 运行时压缩 17.2.2 构建时压缩 第18章 文档化 18.1 JSDoc Toolkit 18.2 YUI Doc 第19章 自动化测试 19.1 YUI Test Selenium引擎 19.1.1 配置一台Selenium服务器 19.1.2 配置YUI Test Selenium引擎 19.1.3 使用YUI Test Selenium引擎 19.1.4 Ant的配置写法 19.2 Yeti 19.3 PhantomJS 19.3.1 安装及使用 19.3.2 Ant的配置写法 19.4 JsTestDriver 19.4.1 安装及使用 19.4.2 Ant的配置写法 第20章 组装到一起 20.1 被忽略的细节 20.2 编制打包计划 20.2.1 开发版本的构建 20.2.2 集成版本的构建 20.2.3 发布版本的构建 20.3 使用CI系统 20.3.1 Jenkins 20.3.2 其他CI系统 附录A JavaScript编码风格指南 附录B JavaScript工具集
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值