资讯专栏INFORMATION COLUMN

<<编写可维护的javascript>> 笔记2(注释)

renweihub / 750人阅读

摘要:注释是代码中最常见的组成部分它们是另一种形式的文档也是程序员最后才舍得花时间去写的但是对于代码的总体可维护性而言注释是非常重要的一环打开一个没有任何注释的文件就好像趣味冒险但如果给你的时间有限这项任务就变成了折磨适度的添加注释可以解释说明代

注释是代码中最常见的组成部分.它们是另一种形式的文档,也是程序员最后才舍得花时间去写的.但是,对于代码的总体可维护性而言,注释是非常重要的一环.打开一个没有任何注释的文件就好像趣味冒险,但如果给你的时间有限,这项任务就变成了折磨.适度的添加注释可以解释说明代码的来龙去脉,其他开发者就可以不用从头开始阅读代码,而是直接去读代码的任意部分.编程风格通常不会包含对注释的风格约定,但我任务从注释的作用即可看出它们的重要性不容忽视.

js支持两种不同类型的注释: 单行注释和多行注释.

2.1 单行注释
单行注释有三种使用方法:

独占一行的注释,用来解释下一行代码.这行注释之前总是有一个空行,且缩进层级和下级代码保持一致.

在代码行的尾部的注释.代码结束到注释之间至少有一个缩进.注释(包括之前的代码部分)不应当超过单行最大字符数限制,如果超过了,就将这条注释放置于当前代码行的上方.

被注释掉的大段代码(很多编辑器都可以批量注释掉多行代码).

单行注释不应当以连续多行注释的形式出现,除非你注释掉一大段代码.只有当需要注释一段很长的文本是才使用多行注释.

// 好的写法
if(condition){
    
    // 如果代码执行到这里,则表明通过了所有安全性检查
    allowed();
}

// 不好的写法
if(condition){
    // 如果代码执行到这里,则表明通过了所有安全性检查
    allowed();
}

// 不好的写法: 错误的缩进
if(condition){
// 如果代码执行到这里,则表明通过了所有安全性检查
    allowed();
}

// 好的写法
var result = something + somethingElse; // somethingElse不应当取值为null

// 不好的写法: 代码和注释之间没有间隔
var result = something + somethingElse;// somethingElse不应当取值为null

// 好的写法
// if(condition) {
//    doSomething();
//    thenDoSomethingElse();
// }

// 不好的写法
// 接下来这段代码非常难, 那么, 让我详细解释一下
// 这段代码的作用是首先判断天剑是否为真
// 只有为真时才会执行, 这里的条件是通过
// 多个函数计算出来的, 在整个回话生命周期内
// 整个值是可以被修改的
if(condition) {
    
    // 如果代码执行到这里, 则表明通过了所有安全性检查
    allowed();
}

2.2 多行注释

// 合法的多行注释
/* 我的注释 */
/* 另一段注释
这段注释包含两行*/
/*
又是一段注释
这段注释同样包含两行
*/

//逼格高,更加清晰.java风格注释
/*
 * 另一段注释
 * 这段注释包含两行文本
 */

多行注释总是会出现在将要描述的代码段之前, 注释和代码之间没有空行间隔. 和单行注释一样, 多行注释之前应当有一个空行, 且缩进层级和其描述的代码保持一致.

// 好的写法
if(condition){
    
    /*
     * 如果代码段执行到这里
     * 说明通过了所有的安全性检测
     */
    allowed();
}

// 不好的写法: 注释之前无空行
if(condition){
    /*
     * 如果代码段执行到这里
     * 说明通过了所有的安全性检测
     */
    allowed();
}

// 不好的写法: 星号后没有空格
if(condition){
    /*
     *如果代码段执行到这里
     *说明通过了所有的安全性检测
     */
    allowed();
}

// 不好的写法: 错误的缩进
if(condition){

/*
 * 如果代码段执行到这里
 * 说明通过了所有的安全性检测
 */
    allowed();
}

// 不好的写法: 代码尾部注释不要用多行注释格式
var result = something + somethingElse; /*somethingElse 不应当取值为null*/

2.3 使用注释
通行的指导原则是:当代码不够清晰时添加注释, 当代码很明了时不应该添加注释.

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, 如果有原型属性,
     * 则逻辑结束并返回received
     */
    if(!from || !to) {
        return receiver;
    }
}else {
    from = supplier;
    to = receiver;
}

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

2.3.2 可能被误认为错误的代码
另一个适合添加注释的好时机是当代码看上去有错误时. 在团队开发中, 总是会有一些好心的开发者在编辑代码时发现他人的代码错误, 就立即修复. 有时这段代码并不是错误的源头, 所以"修复"这个错误往往会制造其他的错误, 因此本次修改应当是可追踪的. 当你写的代码有可能会被别的开发者任务是有错误时, 则需要添加注释.

while(element && (element = element[axis])) {
    if((all || element[]TAG_NAME) &&
            (!fn || fn(elemtnt))) {
        return element;
    }
}

这个例子中, 开发者在while循环控制条件中使用了一个赋值运算符. 这不是一种标准用法, 并常常被检测工具认为是有问题的. 如果你对这段代码不熟悉, 读到这段没有注释的代码时, 很有可能误认为这是一个错误, 猜想作者的本意是使用比较运算符==而不是赋值运算符=. 这行末尾的注释说明作者是有意为之, 即赋值而非比较. 这样, 其他开发者读到这段代码时就不会将它"修复".

2.3.3 浏览器特性hack
js程序员常常会编写一些低效的、不雅的、彻头彻尾的脏代码, 用来让低级浏览器正常工作. 实际上这种情形是一种特殊的"可能被误认为错误的代码": 这种不明显的做浏览器特性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]) {
    if(element === needle ||
            !!(element[COMPARE_DOCUMENT_POSITION](needle) & 16)){
        ret = true;
    }
}

return ret;

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

2.4 文档注释
文档注释并不是js的组成部分, 但是应用很广泛. 最流行的格式是JavaDoc文档格式: 多行注释以单斜线加双星号(/**)开始, 接下来是描述信息, 其中使用@符号来表示一个或多个属性.

/**
如果需要深拷贝(deep copy), 请使用"clone()"
@method merge
@param {Object} 被合并的一个或多个对象
@return {Object} 一个新的合并后的对象
**/
Y.merge = function() {
    var args = arguments,
        i = 0,
        len = args.length,
        result = {};
        
    for(; i < len; ++i) {
        Y.mix(result, args[i], true);
    }
    
    return result;
}

所有的方法

应当对方法、期望的参数和可能返回的值添加注释描述.

所有的构造函数

应当对自定义类型和期望的参数添加注释描述.

所有包含文档化方法的对象

如果一个对象包含一个或多个附带文档注释的方法, 那么这个对象也应当适当地针对文档生成工具添加文档注释

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/87318.html

相关文章

  • &lt;&lt;编写维护javascript&gt;&gt; 笔记3(语句和表达式)

    摘要:所有的块语句都应当使用花括号包括花括号的对齐方式第一种风格第二种风格块语句间隔第一种在语句名圆括号和左花括号之间没有空格间隔第二种在左圆括号之前和右圆括号之后各添加一个空格第三种在左圆括号后和右圆括号前各添加一个空格我个人喜欢在右括号之后添 所有的块语句都应当使用花括号, 包括: if for while do...while... try...catch...finally 3....

    OBKoro1 评论0 收藏0
  • &lt;&lt;编写维护javascript&gt;&gt; 笔记1(基本格式化)

    摘要:程序是写给人读的只是偶尔让计算机执行一下当你刚刚组建一个团队时团队中的每个人都各自有一套编程习惯毕竟每个成员都有着不同的背景有些人可能来自某个皮包公司身兼数职在公司里面什么事都做还有些人会来自不同的团队对某种特定的做事风格情有独钟或恨之入骨 程序是写给人读的,只是偶尔让计算机执行一下. Donald Knuth 当你刚刚组建一个团队时,团队中的每个人都各自有一套编程习惯.毕竟,...

    wfc_666 评论0 收藏0
  • &lt;&lt;编写维护javascript&gt;&gt; 笔记9(将配置数据从代码中分离出来

    摘要:代码无非是定义一些指令的集合让计算机来执行我们常常将数据传入计算机由指令对数据进行操作并最终产生一个结果当不得不修改数据时问题就来了任何时候你修改源代码都会有引入的风险且值修改一些数据的值也会带来一些不必要的风险因为数据时不应当影响指令的正 代码无非是定义一些指令的集合让计算机来执行. 我们常常将数据传入计算机, 由指令对数据进行操作, 并最终产生一个结果. 当不得不修改数据时问题就来...

    xbynet 评论0 收藏0
  • &lt;&lt;编写维护javascript&gt;&gt; 笔记5(UI层松耦合)

    摘要:由于第四章太稀松平常了于是就直接跳到第五章了这里我就草草的说一下第四章的几个点吧在严格模式的应用下不推荐将用在全局作用域中相等推荐尽量使用和守则如果是在没有别的方法来完成当前任务这时可以使用原始包装类型不推荐创建类型时用等创建类型从这一章节 由于第四章太稀松平常了, 于是就直接跳到第五章了.这里我就草草的说一下第四章的几个点吧 在严格模式的应用下 不推荐将use strict;用在全...

    saucxs 评论0 收藏0
  • &lt;&lt;编写维护javascript&gt;&gt; 笔记7(事件处理)

    摘要:在所有应用中事件处理都是非常重要的所有的均通过事件绑定到上所以大多数前端工程师需要花费很多时间来编写和修改事件处理程序遗憾的是在诞生之初这部分内容并未受太多重视甚至当开发者们开始热衷于将传统的软件架构概念融入到里时事件绑定仍然没有收到多大重 在所有JavaScript应用中事件处理都是非常重要的. 所有的JavaScript均通过事件绑定到UI上, 所以大多数前端工程师需要花费很多时间...

    microelec 评论0 收藏0

发表评论

0条评论

renweihub

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<