《编写可维护的JavaScript》——2.3 使用注释

简介: 另一个适合添加注释的好时机是当代码看上去有错误时。在团队开发中,总是会有一些好心的开发者在编辑代码时发现他人的代码错误,就立即将它修复。有时这段代码并不是错误的源头,所以“修复”这个错误往往会制造其他错误,因此本次修改应当是可追踪的。

本节书摘来自异步社区《编写可维护的JavaScript》一书中的第2章,第2.3节,作者:【美】Nicholas C. Zakas著,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.3 使用注释

何时添加注释是程序员经常争论的一个话题。一种通行的指导原则是,当代码不够清晰时添加注释,而当代码很明了时不应当添加注释。比如这个例子中,注释是画蛇添足。

// 不好的写法
// 初始化count
var count = 10;

因为代码中初始化count的操作是显而易见的。注释并没有提供其他有价值的信息。换个角度讲,如果这个值10具有一些特殊的含义,而且无法直接从代码中看出来,这时就有必要添加注释了。

// 好的写法
// 改变这个值可能会让它变成青蛙
var count = 10;

当然不可能因为修改了count的值它就变成了青蛙,但这的确是一个好的注释写法的例子,因为注释中给出了必要的信息,如果没有注释,你不可能获得这些信息。想象一下如果你修改了count的值它真的变成了青蛙,实在是让人困惑不解,一切都源于你没有写这句注释。

因此,添加注释的一般原则是,在需要让代码变得更清晰时添加注释。

2.3.1 难于理解的代码
难于理解的代码通常都应当加注释。根据代码的用途,你可以用单行注释、多行注释,或是混用这两种注释。关键是让其他人更容易读懂这段代码。比如,这段示例代码摘自YUI类库中的Y.mix()方法。

// 好的写法
if (mode) {
     /*
      * 当mode为2时(原型到原型,对象到对象),这里只递归执行一次
      * 用来执行原型到原型的合并操作。对象到对象的合并操作
      * 将会被挂起,在合适的时机执行
      */
     if (mode === 2) {
          Y.mix(receiver.prototype, supplier.prototype, overwrite,
                    whitelist, 0, merge);
    }
     /*
      * 根据指定的模式类型,我们可能会从源对象拷贝至原型中,
      * 或是从原型拷贝至接收对象中
      */
     from = mode === 1 || mode === 3 ? supplier.prototype : supplier;
     to   = mode === 1 || mode === 4 ? receiver.prototype : receiver;
     /*
      * 如果supplier或receiver不含有原型属性时,
      * 则逻辑结束,并返回undefined。如果有原型属性,
      * 则逻辑结束并返回receiver
      */
     if (!from || !to) {
          return receiver;
    }
} else {
     from = supplier;
     to   = receiver;
}

Y.mix()方法使用常量来决定如何处理。mode参数就表示这些常量其中之一,但仅仅通过这些数值无法理解它们各自代表的含义。这里的注释非常棒,因为它及时地解释了这里复杂的决策逻辑。

2.3.2 可能被误认为错误的代码
另一个适合添加注释的好时机是当代码看上去有错误时。在团队开发中,总是会有一些好心的开发者在编辑代码时发现他人的代码错误,就立即将它修复。有时这段代码并不是错误的源头,所以“修复”这个错误往往会制造其他错误,因此本次修改应当是可追踪的。当你写的代码有可能会被别的开发者认为有错误时,则需要添加注释。这里是另一段来自YUI源码的例子。
while (element &&(element = element[axis])) { // 提示: 赋值操作 if ( (all || element[TAG_NAME]) && (!fn || fn(element)) ) { return element; } } 在这个例子中,开发者在while循环控制条件中使用了一个赋值运算符。这不是一种标准用法,并常常被检测工具认为是有问题的。如果你对这段代码不熟悉,读到这段没有注释的代码时,很可能误以为这是一个错误,猜想作者的本意是使用比较运算符==而不是赋值运算符=。这行末尾的注释说明作者是有意为之,即赋值而非比较。这样,其他开发者在读到这段代码时就不会将它“修复”。

2.3.3 浏览器特性hack
JavaScript程序员常常会编写一些低效的、不雅的、彻头彻尾的肮脏代码,用来让低级浏览器正常工作。实际上这种情形是一种特殊的“可能被误认为错误的代码”:这种不明显的做浏览器特性Hack的代码可能隐含一些错误。这里有个例子,是摘自YUI类库的Y.DOM.contains()方法。

var ret = false;
if ( !needle || !element || !needle[NODE_TYPE] || !element[NODE_TYPE]) {
    ret = false;
} else if (element[CONTAINS]) {
    // 如果needle不是ELEMENT_NODE时,IE和Safari下会有错误
    if (Y.UA.opera || needle[NODE_TYPE] === 1) {
         ret = element[CONTAINS](needle);
    } else {
         ret = Y_DOM._bruteContains(element, needle);
    }
} else if (element[COMPARE_DOCUMENT_POSITION]) { // gecko
     if (element === needle || !!(element[COMPARE_DOCUMENT_POSITION](needle) & 16)) {
         ret = true;
     }
}
return ret;

这段代码的第6行包含一条重要的注释。尽管IE和Safari中都有内置方法contains(),但如果needle不是一个元素时,这个方法会报错。所以只有当浏览器是Opera时才能用这个方法,其他浏览器中needle必须是一个元素(nodeType是1)。这里关于浏览器的说明同样解释了为什么需要一个if语句,这个注释不仅确保将来不会被其他人误改动,而且在代码编写者回过头阅读自己的这段代码时,也会适时地针对新版本的IE和Safari的兼容情况做出调整。

相关文章
|
5月前
|
分布式计算 JavaScript 前端开发
js手写面试题【附带注释】
js手写面试题【附带注释】
48 0
|
19天前
|
JSON 前端开发 JavaScript
【2024-04-22 源码】最新PDF批注注释插件库,pdf.js插件库,纯前端离线JavaScript库(PDF高亮、下划线、橡皮擦、文本框、画笔、历史记录)
一款基于 pdf.js 开发的PDF批注插件库,支持纯离线内网部署,功能完善、强大且在不断升级,极易上手,欢迎关注!
35 4
【2024-04-22 源码】最新PDF批注注释插件库,pdf.js插件库,纯前端离线JavaScript库(PDF高亮、下划线、橡皮擦、文本框、画笔、历史记录)
|
7月前
|
JavaScript 前端开发 Windows
VScode的注释和标题,标签,img的src属性(如何网页上插入图片)(Mac如何开启js控制台)(如何免费复制网页中的文字)
VScode的注释和标题,标签,img的src属性(如何网页上插入图片)(Mac如何开启js控制台)(如何免费复制网页中的文字)
|
2月前
|
JavaScript 前端开发 C++
javascript的语句和注释
javascript的语句和注释
|
3月前
|
JavaScript 前端开发
JavaScript 注释方式
JavaScript 注释方式
17 2
|
4月前
|
JavaScript 前端开发 Java
小笔记:如何使用代码注释:关于JavaScript与TypeScript 注释和文档的自动生成
小笔记:如何使用代码注释:关于JavaScript与TypeScript 注释和文档的自动生成
220 0
|
4月前
|
JSON JavaScript 前端开发
原生js做树形菜单(详细注释+加简易版)
原生js做树形菜单(详细注释+加简易版)
26 0
|
5月前
|
JavaScript 前端开发 索引
某东大厂面试js手写题【手写代码附带注释,放心食用,博主亲测】
某东大厂面试js手写题【手写代码附带注释,放心食用,博主亲测】
40 0
|
6月前
|
JavaScript 前端开发 算法
LeetCode 37.解数独(注释完整+JavaScript解题)
LeetCode 37.解数独(注释完整+JavaScript解题)
38 0
|
6月前
|
JSON JavaScript 前端开发
【2023-11-01】一款基于 pdf.js 的 PDF 批注注释插件库(纯JS、高亮、画笔、多边形、历史记录)
基于纯 JavaScript 和 PDF.js 做的一款 PDF 批注拓展插件-PDFMaster,一款仍能兼容支持IE 11的PDF批注插件,界面美观功能强大,有无开发经验都可以快速简单快速使用。
155 0
【2023-11-01】一款基于 pdf.js 的 PDF 批注注释插件库(纯JS、高亮、画笔、多边形、历史记录)