《编写可维护的JavaScript》——第 1 章 基本的格式化1.1 缩进层级

第一部分 编程风格

编写可维护的JavaScript
“程序是写给人读的,只是偶尔让计算机执行一下。”

——Donald Knuth。1

当你刚刚组建一个团队时,团队中的每个人都各自有一套编程习惯。毕竟,每个成员都有着不同的背景。有些人可能来自某个“皮包公司”(one-man shop),身兼数职,在公司里什么事都做;还有些人会来自不同的团队,对某种特定的做事风格情有独钟(或恨之入骨)。每个人都觉得代码应当按照自己的想法来写,这些通常被归纳为个人编程嗜好。在这个过程中2应当尽早将确定统一的编程风格纳入议题。

我们会经常碰到这两个术语:“编程风格”(style guideline)和“编码规范”(code convention)。编程风格是编码规范的一种,用来规约单文件中代码的规划。编码规范还包含编程最佳实践、文件和目录的规划以及注释等方面。本书集中讨论JavaScript的编码规范。

为什么要讨论编程风格
提炼编程风格是一道工序,花再多的时间也不为过。毕竟每个人都有自己的想法,如果一天当中你有8小时是在写代码,那么你自然希望用一种舒服的方式来写代码。刚开始,团队成员对新的编程风格有点不适应,全靠强势的项目组长强制推行才得以持续。一旦风格确立后,这套编程风格就会促成团队成员高水准的协作,因为所有代码(的风格)看起来极为类似。

在团队开发中,所有的代码看起来风格一致是极其重要的,原因有以下几点。

任何开发者都不会在乎某个文件的作者是谁,也没有必要花费额外精力去理解代码逻辑并重新排版,因为所有代码排版格式看起来非常一致。我们打开一个文件时所干的第一件事,常常不是立即开始工作而是首先修复代码的缩进,当项目很庞大时,你会体会到统一的编程风格的确大幅度节省了时间成本。
我能很容易地识别出问题代码并发现错误。如果所有代码看起来很像,当你看到一段与众不同的代码时,很可能错误就产生在这段代码中。
毫无疑问,全球性的大公司都对外或对内发布过编程风格文档。

编程风格是个人的事情,只有放到团队开发中才能发挥作用。本书的这部分给出了JavaScript编码规范中值得关注(推荐)的方面。在某些场景中,很难说哪种编程风格好,哪种编程风格不好,因为有些编程风格只是某些人的偏好。本章不是向你灌输我个人的风格偏好,而是提炼出了编程风格应当遵循的重要的通用准则。本书附录A中给出了我个人的JavaScript编程风格。

有用的工具
开发编码指南是一件非常困难的事情—执行是另外一回事。在团队中通过讨论达成一致和进行代码评审(code review)时,每个人都很关注编码风格,但在平时大家却常常将这些抛在脑后。工具可以对每个人实时跟踪。这里有两个用来检查编程风格的工具,这两个工具非常有用:JSLint和JSHint。

JSLint是由Douglas Crockford创建的。这是一个通用的JavaScript代码质量检查工具。最开始,JSLint只是一个简单的查找不符合JavaScript模式的、错误的小工具。经过数年的进化,JSLint已经成为一个有用的工具,不仅仅可以找出代码中潜在的错误,而且能针对你的代码给出编码风格上的警告。

Crockford将他对JavaScript风格的观点分成了三个不同的部分。

“JavaScript风格的组成部分(第一部分)”,包含基本的模式和语法。
“JavaScript风格的组成部分(第二部分)”,包含一般性的JavaScript惯用法。
“JavaScript编程语言的编码规范”,这个规范更加全面,从前两部分中提炼出了编程风格的精华部分,同时增补了少量的编程风格指引。
JSLint直接吸纳了很多Crockford所提炼的编程风格,而且很多时候我们无法关闭JSLint中检查编程风格的功能。所以JSLint是一个非常棒的工具,当然前提是你认可Crockford关于编程风格的观点。

JSHint是JSLint的一个分支项目,由Anton Kovalyov创建并维护。JSHint的目标是提供更加个性化的JavaScript代码质量和编程风格检查的工具。比如,当出现语法错误的时候,JSHint几乎可以关掉所有编程风格检查,这样你可以完全自定义消息提示。Kovalyov非常鼓励大家通过GitHub上的源代码库参与JSHint项目并为之贡献代码。

你可以将这些工具中的一种集成到打包过程中,通过这种方式推行编码规范是一个不错的方法。这种方法同时可以监控你的JavaScript代码中潜在的错误。

第 1 章 基本的格式化

编程风格指南的核心是基本的格式化规则(formatting rule)。这些规则直接决定了如何编写高水准的代码。与在学校学习写字时所用的方格纸类似,基本的格式化规则将指引开发者以特定的风格编写代码。这些规则通常包含一些你不太在意的有关语法的信息,但对于编写清晰连贯的代码段来说,每一条信息都是非常重要的

1.1 缩进层级

关于JavaScript编码风格,我们首先要讨论的是(几乎所有的语言都是如此)如何处理缩进。对这个话题是可以争论上好几个小时的,缩进甚至关系到软件工程师的价值观。在确定编程风格之初应当首先确定缩进格式,这非常重要,以免工程师后续会陷入那个老生常谈的打开文件时二话不说先重排代码缩进的问题之中。来看一下这段代码(为了演示,这里故意修改了示例代码的缩进)。

if (wl && wl.length) {
               for (i = 0, l = wl.length; i < l; ++i) {
          p = wl[i];
          type = Y.Lang.type(r[p]);
          if (s.hasOwnProperty(p)) { if (merge && type == 'object') {
      Y.mix(r[p], s[p]);
} else if (ov || !(p in r)) {
                        r[p] = s[p];
               }
        }
    }
}

快速读懂这段代码并不容易。这里的缩进并不统一,一眼看去else是对应到第1行的if语句。但实际上这个else和代码第5行的if语句相对应。罪魁祸首是多位开发人员在同一段代码里应用了不同的缩进风格。这恰恰说明了统一缩进风格的重要性。如果有适当的缩进,这段代码将变得更加易读。

if (wl && wl.length) {
     for (i = 0, l = wl.length; i < l; ++i) {
          p = wl[i];
          type = Y.Lang.type(r[p]);
          if (s.hasOwnProperty(p)) {
               if (merge && type == 'object') {
                    Y.mix(r[p], s[p]);
               } else if (ov || !(p in r)) {
                    r[p] = s[p];
               }
          }
     }
}

坚持使用适度的缩进是万里长征的第一步—本章在下面将提到这种做法可以带来其他可维护性方面的提升。

对于大多数编程风格来说,代码到底应该如何缩进并没有统一的共识。有两种主张。

使用制表符进行缩进

每一个缩进层级都用单独的制表符(tab character)表示。所以一个缩进层级是一个制表符,两个缩进层级为两个制表符,以此类推。这种方法有两个主要的好处。第一,制表符和缩进层级之间是一对一的关系,这是符合逻辑的。第二,文本编辑器可以配置制表符的展现长度1,因此那些想修改缩进尺寸的开发者可以通过配置文本编辑器来实现,想长即长,想短可短。使用制表符作缩进的主要缺点是,系统对制表符的解释不一致。你会发觉在某个系统中用一款编辑器打开文件时看到的缩进,和在另外一个系统中用相同的编辑器打开文件时看到的不一样。对于那些追求(代码展现)一致性的开发者来说,这会带来一些困惑。这些差异、争论会导致不同的开发者对同一段代码有不同的看法的,而这些正是团队开发需要规避的。

使用空格符进行缩进

每个缩进层级由多个空格字符组成。在这种观点中有三种具体的做法:2个空格表示一个缩进,2个空格表示一个缩进,以及8个空格表示一个缩进。这三种做法在其他很多编程语言中都能找到渊源。实际上,很多团队选择4个空格的缩进,对于那些习惯用2个空格缩进和用8个空格缩进的人来说,4个空格缩进是一种折中的选择。使用空格作缩进的好处是,在所有的系统和编辑器中,文件的展现格式不会有任何差异。可以在文本编辑器中配置敲击Tab键时插入几个空格。也就是说所有开发者都可以看到一模一样的代码呈现。使用空格缩进的缺点是,对于单个开发者来说,使用一个没有配置好的文本编辑器创建格式化的代码的方式非常原始。

尽管有人争辩说应当优先考虑使用一种缩进约定,但说到底这只是一个团队偏好的问题。这里我们给出一些各式各样的缩进风格作为参考。

. jQuery核心风格指南(jQuery Core Style Guide)明确规定使用制表符缩进。
. Dauglas Crockford的JavaScript代码规范(Douglas Crockford’s Code Conventions for the JavaScript Programming Language)规定使用4个空格字符的缩进。
. SproutCore风格指南(SproutCore Style Guide)规定使用2个空格的缩进。
. Goolge的JavaScript风格指南(Google JavaScript Style Guide)规定使用2个空格的缩进。
. Dojo编程风格指南(Dojo Style Guide)规定使用制表符缩进。
我推荐使用4个空格字符为一个缩进层级。很多文本编辑器都默认将缩进设置为4个空格,你可以在编辑器中配置敲入Tab键时插入4个空格。使用2个空格的缩进时,代码的视觉展现并不是最优的,至少看起来是这样。

尽管是选择制表符还是选择空格做缩进只是一种个人偏好,但绝对不要将两者混用,这非常重要。这么做会导致文件的格式很糟糕,而且需要做不少清理工作,就像本节的第一段示例代码显示的那样。

时间: 2024-11-10 08:03:00

《编写可维护的JavaScript》——第 1 章 基本的格式化1.1 缩进层级的相关文章

《编写可维护的JavaScript》——第 1 章 基本的格式化 1.1缩进层级

第 1 章 基本的格式化 编程风格指南的核心是基本的格式化规则(formatting rule).这些规则直接决定了如何编写高水准的代码.与在学校学习写字时所用的方格纸类似,基本的格式化规则将指引开发者以特定的风格编写代码.这些规则通常包含一些你不太在意的有关语法的信息,但对于编写清晰连贯的代码段来说,每一条信息都是非常重要的.1.1 缩进层级 关于JavaScript编码风格,我们首先要讨论的是(几乎所有的语言都是如此)如何处理缩进.对这个话题是可以争论上好几个小时的,缩进甚至关系到软件工程师

《编写可维护的JavaScript》——第 2 章 注释 2.1单行注释

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

《编写可维护的JavaScript》——第 2 章 注释2.1 单行注释

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

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

2.3 使用注释 何时添加注释是程序员经常争论的一个话题.一种通行的指导原则是,当代码不够清晰时添加注释,而当代码很明了时不应当添加注释.比如这个例子中,注释是画蛇添足. // 不好的写法 // 初始化count var count = 10; 因为代码中初始化count的操作是显而易见的.注释并没有提供其他有价值的信息.换个角度讲,如果这个值10具有一些特殊的含义,而且无法直接从代码中看出来,这时就有必要添加注释了. // 好的写法 // 改变这个值可能会让它变成青蛙 var count =

《编写可维护的JavaScript》——1.7 直接量

1.7 直接量 JavaScript中包含一些类型的原始值:字符串.数字.布尔值.null和undefined.同样也包含对象直接量和数组直接量.这其中,只有布尔值是自解释(self-explanatory)的,其他的类型或多或少都需要思考一下它们如何才能更精确地表示出来. ** 1.7.1 字符串** 在JavaScript中,字符串是独一无二的.字符串可以用双引号括起来,也可以用单引号括起来.比如: // 合法的JavaScript代码 var name = "Nicholas says,

《编写可维护的JavaScript》——1.2 语句结尾

1.2 语句结尾 有一件很有意思且很容易让人困惑的事情,那就是JavaScript的语句要么独占一行,要么以分号结尾.类似C的编程语言,诸如C++和Java,都采用这种行结束写法,即结尾使用分号.下面这两段示例代码都是合法的JavaScript. // 合法的代码 var name = "Nicholas"; function sayName() { alert(name); } // 合法的代码,但不推荐这样写 var name = "Nicholas" func

《编写可维护的JavaScript》——2.4 文档注释

2.4 文档注释 从技术的角度讲,文档注释并不是JavaScript的组成部分,但它们是一种普遍的实践.文档注释有很多种格式,但最流行的一种格式来自于JavaDoc文档格式:多行注释以单斜线加双星号(/**)开始,接下来是描述信息,其中使用@符号来表示一个或多个属性.来看一段来自YUI的源码的例子. /** 返回一个对象,这个对象包含被提供对象的所有属性. 后一个对象的属性会覆盖前一个对象的属性. 传入一个单独的对象,会创建一个它的浅拷贝(shallow copy). 如果需要深拷贝(deep

《编写可维护的JavaScript》——1.6 命名

1.6 命名 "计算机科学只存在两个难题:缓存失效和命名."-Phil Karlton. 只要是写代码,都会涉及变量和函数,因此变量和函数命名对于增强代码可读性至关重要.JavaScript语言的核心ECMAScript,即是遵照了驼峰式大小写(Camel case)1命名法.驼峰式大小写(Camel Case)命名法是由小写字母开始的,后续每个单词首字母都大写,比如: var thisIsMyName; var anotherVariable; var aVeryLongVariab

《编写可维护的JavaScript》——2.2 多行注释

2.2 多行注释 多行注释可以包裹跨行文本.它以/开始,以/结束.多行注释不仅仅可以用来包裹跨行文本,这取决于你.下面这些都是合法的注释. /* 我的注释 */ /* 另一段注释 这段注释包含两行 */ /* 又是一段注释 这段注释同样包含两行 */ 尽管从技术的角度看,这些注释都是合法的,但我比较青睐Java风格的多行注释.Java风格的注释至少包含三行:第一行是/,第二行是以开始且和上一行的保持左对齐,最后一行是/.这种注释看起来像下面这样. /* * 另一段注释 * 这段注释包含两行文本