浅谈 JavaScript 编程语言的编码规范--转载

原文:http://www.ibm.com/developerworks/cn/web/1008_wangdd_jscodingrule/

对于熟悉 C/C++ 或 Java 语言的工程师来说,JavaScript 显得灵活,简单易懂,对代码的格式的要求也相对松散。很容易学习,并运用到自己的代码中。也正因为这样,JavaScript 的编码规范也往往被轻视,开发过程中修修补补,最终也就演变成为后续维护人员的恶梦。软件存在的长期价值直接与编码的质量成比例。编码规范能帮助我们降低 编程中不必要的麻烦。而 JavaScript 代码是直接发送给客户浏览器的,直接与客户见面,编码的质量更应该受到关注。

本文浅谈 JavaScript 编程中关于编码规范的问题,分析其中缘由。希望引起更多 Web 开发人员对 JavaScript 编码规范问题的关注和对软件产品质量问题的重视。

前言

提及 C/C++ 和 Java 编码规范,相信许多工程师并不生疏。但说到 JavaScript 语言的编码规范,也许您会忍俊不禁。JavaScript 不是语法很灵活吗?变量随时用随时可以声明;语句结束符可以不要;字符串和数字也可以相加;参数多一个少一个也不会报错。没错,当您从 C/C++ 和 Java 严格的语法规定之下,转向 JavaScript 语言,会觉得自由了很多,轻松了很多。语法松散是 JavaScript 重要的特征。它灵活易懂,给开发人员带来了很多方便,但如果编写过程中不注意,代码的调试成本和维护成本则会无形地增加。

JavaScript 编码会随应被直接发送到客户端的浏览器,代码规范不只是代码质量的保证,也影响到产品的长期信誉。希望 JavaScript 编程语言的规范问题也能同样引起更多朋友的关注。

JavaScript 编码规范建议

本文就 JavaScript 编码过程中涉及的排版、命名、声明、作用域、及一些特殊符号的使用等方面,根据个人在学习工作中的总结,给出自己的一些建议,并分析其中缘由,以供参考。

JavaScript 文件引用

JavaScript 程序应该尽量放在 .js 的文件中,需要调用的时候在 HTML 中以 <script src="filename.js"> 的形式包含进来。JavaScript 代码若不是该 HTML 文件所专用的,则应尽量避免在 HTML 文件中直接编写 JavaScript 代码。因为这样会大大增加 HTML 文件的大小,无益于代码的压缩和缓存的使用。

另外,<script src="filename.js"> 标签应尽量放在文件的后面。这样会降低因加载 JavaScript 代码而影响页面中其它组件的加载时间。

代码排版

行长度

每行代码应小于 80 个字符。如果代码较长,应尽量选择换行,下一行代码应缩进 8 个空格。这样可以使代码排版整齐,减轻阅读代码的疲劳感。换行缩进 8 个空格可以和代码段的缩进 4 个空格区分开,以增强代码的可阅读性。

行结束

JavaScript 语句应该以分号结束。但大多数浏览器允许不写分号,只要在本应是分号的地方有一个换行符就行。但是如果代码行较长需要换行的时候,有哪些注意事项呢?换行 应选择在操作符和标点符号之后,最好是在逗号','之后,而不要在变量名、字符串、数字、或')' ']' '++' '--'等符号之后换行。

这样可以有效的防止拷贝、粘贴而引起的错误,并可有效地增强代码的可阅读性。请见清单 1,代码的输出符合我们的期望。但就写法而言,对 valueB 的赋值语句是在变量 valueA 之后进行的换行,这很容易被误解为 valueB=ValueA,给阅读造成障碍。而对 valueC 的复制语句是在'+'之后进行的换行,就容易理解的多。这也是本文所提倡的换行方式。


清单 1. 行结束的位置

			<script language="javascript"> var valueA = 1; var valueB = valueA         ///bad +1; var valueC = valueB +      ///good valueA; alert(valueB);              //output: valueB=2 alert(valueC);//output: valueC=3 </script> 

缩进

关于缩进的问题,不只是 JavaScript,几乎所有的语言编写的时候,都会提及缩进的问题。缩进几乎是代码编写规范的第一课,是代码可阅读性判断的直接因素。

代码缩进的好处是不言而喻的,但是对于如何缩进,则没有标准而言。最受欢迎的是方便使用 TAB 键缩进,也有些喜欢用 2 个、4 个、8 个空格进行缩进。这样缩进风格不一,也同样给代码的阅读带来障碍。

本文提倡用 4 个空格来进行缩进,并在同一产品中采用同一种缩进标准。不支持用 TAB 键进行缩进。这是因为直到现在还没有统一的标准来定义 TAB 键所代替的空白大小,有些编辑器解析为 4 个空格大小,有些则解析为 8 个。因而用不同的编辑器查看代码,可能造成格式混乱。当然 TAB 简单易用,为解决这个问题,建议在设置开发环境时,将编辑器里的 TAB 快捷键重新设置为 4 个空格。据了解 Eclipse, Vi, Nodepad++,Editplus, UltraEdit 等流行的编辑器,均提供了此功能。

注释

代码中的注释很重要,自然也是毋庸置疑的。通常我们会强调代码中注释数量的多少,而轻视了对注释质量的提高。编码是及时添加注释,会给后续 代码的维护人员带来很大的便利。但是如果注释不注意更新,或者由于拷贝、粘贴引起的错误的注释,则会误导阅读人员,反而给阅读带来障碍。

除了注释要 及时更新外,我们还应对注释的内容要特别关注。注释要尽量简单、清晰明了,避免使用含混晦涩的语言,同时着重 注释的意义,对不太直观的部分进行注解。请见清单 2。


清单 2. 有意义的注释

 <script language="javascript"> //following section is used to initialize golbal variables             (good) var valueA = 0;     //initialize  valueA to be sero                       (bad) var valueB = 1; ... //call f1 function after waiting for 50 seconds.                         (good) setTimeout(f1,50000); //set timeout to be 20s                     (copy error) ... </script> 

这样的注释方式在 JavaScript 代码中经常见到。"initialize valueA to be sero" 这样的注释有什么用呢?难道阅读程序的工程师从"var valueA = 0;"复制语句中看不出来么?"set timeout to be 20s"这条注释,不只是因拷贝、粘贴引起的时间大小的错误,同时也误导了程序员对这条语句的理解。setTimeout() 函数的作用并非是设置函数执行的超时时间,而是等待一定时间后执行所调用的函数,害人匪浅呀。这样的注释内容宁可删掉。

此外,JavaScript 的注释有两种"//" 和"/* .... */",建议"//"用作代码行注释,"/* .... */"形式用作对整个代码段的注销,或较正式的声明中,如函数参数、功能、文件功能等的描述中。

标识符命名

JavaScript 中的标识符的命名规则:

  • 以字母、下划线'_'或美元符号'$'开头
  • 允许名称中包含字母,数字,下划线'_'和美元符号'$'
  • 区分大小写

变量、参数、成员变量、函数等名称均以小写字母开头,构造器的名称以大写字母开头。下划线'_'开头的变量一般习惯于标识私有 / 局部成员。而美元符号'$'开头的变量习惯于标识系统相关,比如系统进程等。应避免用下划线'_'或美元符号'$'来命名标识符。尽可能地降低代码的阅读 负担。

声明

变量的声明

尽管 JavaScript 语言并不要求在变量使用前先对变量进行声明。但我们还是应该养成这个好习惯。这样可以比较容易的检测出那些未经声明的变量,避免其变为隐藏的全局变量,造成隐患。

在函数的开始应先用 var 关键字声明函数中要使用的局部变量,注释变量的功能及代表的含义,且应以字母顺序排序。每个变量单独占一行,以便添加注释。这是因为 JavaScript 中只有函数的 {} 表明作用域,用 var 关键字声明的局部变量只在函数内有效,而未经 var 声明的变量则被视为全局变量。我们来看下清单 3。


清单 3. 局部变量声明

			 <script language="javascript"> var valueA  = "a"; var valueB  = "b"; function f1() { var valueA = "c"; alert("valueA="+valueA);        //output: valueA=c valueB = "d"; alert("valueB="+valueB);        //output: valueB=d } f1(); alert("valueA="+valueA);            //output: valueA=a alert("valueB="+valueB);            //output: valueB=d </script> 

从上例的输出惊奇地发现,用 var 声明过的变量 valueA 和没有声明的变量 valueB 是有区别的。特别需要注意的是,在函数内部用 var 声明的变量为局部变量,这样可以有效地避免因局部变量和全局变量同名而产生的错误。

函数的声明

函数也应在调用前进行声明,内部函数应在 var 声明内部变量的语句之后声明,可以清晰地表明内部变量和内部函数的作用域。

此外,函数名紧接左括号'('之间,而右括号')'和后面的'{'之间要有个空格,以清楚地显示函数名以其参数部分,和函数体的开始。若函 数为匿名 / 无名函数,则 function 关键字和左括号'('之间要留空格,否则可能误认为该函数的函数名为 function。


清单 4. 内部函数声明

			 <script language="javascript"> var innerA = 1; function outF() { var innerA = 2; function _inF() { alert("valueA="+innerA); } _inF(); } outF();                         //output: valueA=2 _inF();                         //error: innerF is not defined </script> 

从清单 4 的输出可以看出,inF() 函数仅在 outF() 函数的内部生效,局部变量 innerA 对内部函数的作用域生效。这样的编码方式使得变量和函数的作用域变得清晰。

语句

对于简单语句而言,需要提及的仍然是分号必要性,同时,一行最多有一个语句。如果一个赋值语句是用函数和对象来赋值,可能需要跨多行,一定切记要在赋值语句末加上分号。

这是因为 JavaScript 中,所有表达式都可以当语句,遇换行符时会解析为表达式的结束,此时不规范的换行和分号的丢失,可能引入新的错误。

对于复合语句,if, for, while, do, switch, try … catch 等代码体,函数定义的函数体,对象的定义等都需要放在花括号'{}'里面。

  • '{' 应在行末,标志代码块的开始。
  • '}' 应在一行开头,标志代码块的结束,同时需要和'{'所在行的开始对齐,以表明一个完整的复合语句段。这样可以极大地提高代码的可阅读性,控制逻辑能清晰地表现出来。
  • 被包含的代码段应该再缩进 4 个空格。
  • 即使被包含的代码段只有一句,也应该用花括号'{}'包含。尽管不用花括号代码也不会错,但如若需要增加语句的话,则较容易因花括号遗漏而引起的编译错误或逻辑错误。

return语句在使用时也需慎重,如果用表达式的执行作为返回值,请把表达式和 return 放在同一行中,以免换行符被误解析为语句的结束而引起返回错误。return 关键字后若没有返回表达式,则返回 undefined。构造器的默认返回值为 this。


清单 5. return 表达式

			 <script language="javascript"> function F1() { var valueA  = 1; var valueB  = 2; return valueA + valueB; } function F2() { var valueA  = 1; var valueB  = 2; return valueA + valueB; } alert( F1() );  //output: 3 alert( F2() );  //ouput: undefined </script> 

在清单 5 中显示了因返回表达式没有和 return 关键字放在同一行而引起的返回错误,需重视。

特殊符号

空白符

适当的空白行可以大大提高代码的可阅读性,可以使代码逻辑更清晰易懂。同时,在表达式中适当的留空白,也会给代码的阅读带来方便。

关键字的后面如有括号,则最好在关键字和左括号'('之间留空白,如 for, if, while 等。而函数名和括号之间则不宜留空白,但若是匿名函数,则必须在 function 和左括号'('之间留空白,否则,编辑器会误认为函数名为 function。

在表达式中,二元运算符 ( 除左括号'(',左方括号'[',作用域点'.') 和两个操作数之间最好留空白。一元运算符(若不是词 typeof 等)和其操作数之间不宜留空白。

逗号','的后面需要留空白,以显示明确的参数间隔,变量间隔等。

分号';'之后通常表明表达语句的结束,而应空行。在 for 的条件语句中,分号之后则应该留空白。

{ } 和 [ ]

在 JavaScript 中,如需定义空对象和空数组,通常很自然地想到用 new Object() 和 new Array() 的方法。其实花括号'{}'和方括号'[]'可以直接用来定义一个空对象和一个空数组。这种书写方法可以使代码看起来简单易懂。

== 和 ===

判断"逻辑等"在代码里太平常的不过事情了,但 JavaScript 与其他熟知的编程语言不同的是,除了可以使用两个等号'=='来作判断以为,还可以使用三个等号'==='来进行逻辑等判断。两者的不同是'=='作逻辑 等判断时,会先进行类型转换后再进行比较。'==='则不会。因而,'=='进行的判断结果可能产生偏差。'!='与'!=='的区别亦是如此。本文提倡 尽量使用'==='来进行逻辑等的判断,用'!=='进行逻辑不等的判断。


清单 6. === 的使用

			 <script language="javascript"> var valueA = "1"; var valueB = 1; if ( valueA == valueB) { alert("Equal"); } else { alert("Not equal") } //output: "Equal"if ( valueA === valueB) { alert("Equal"); } else { alert("Not equal") } //output: "Not equal"</script> 

清单 6 中,valueA 和 valueB 两个变量的值显然是不相等的,起码 valueA 是个字符串,而 valueB 是一个数字。但用'=='进行判断是,程序却输出相等的字样。这是因为编译器对两个变量进行比较时,因为他们的类型不同,而自动地将 valueB 转换成字符串,而后再和 valueA 进行比较的。用'==='得到的判断结果正和预期的结果相符。

+

加号'+'也同样是程序员所熟知的操作符之一。JavaScript 和其他编程语言不同的是,在 JavaScript 中,'+'除了表示数字值相加,字符串相连接以外,还可以作一元运算符用,把字符串转换为数字。因而如果使用不当,则可能与自增符'++'混淆而引起计算 错误。这一点,在清单 7 中可以清楚地看出。


清单 7. 巧用 + 号

			 <script language="javascript"> var valueA = 20; var valueB = "10"; alert( valueA + valueB);     //ouput: 2010 alert( valueA + (+valueB)); //output: 30 alert( valueA + +valueB);    //output:30 alert( valueA ++valueB);     //Compile error </script> 

总结

本文就 JavaScript 代码的排版、命名、声明、语句、和一些特殊字符的使用等方面,谈了自己对 JavaScript 编程规范的建议。此外,还有许多方面需要深入了解研究,如 with, eval 语句和 this 对象的使用等等。我们在认识其普遍性的同时也需要注意其特殊性,在编写代码时多用心留意,以创造更多更优质的程序代码。

声明

本文所提及的 JavaScript 编程规范的建议是在学习和工作中归纳出来的,仅供技术交流使用。

参考资料

学习

  • 《 JavaScript: The Definitive Guide 》第五版,http://oreilly.com/catalog/9780596101992,由 David Flanagan 著,O'Reilly 出版,此书是 JavaScript 程序员必不可少的学习参考书;

  • 《 JavaScript 语言精粹》,http://www.china-pub.com/195292,由雅虎资深 JavaScript 架构师 Douglas Crokford 著 , 电子工业大学出版,此书很好地讲述了如何用 JavaScript 创建真正可扩展的和高效的代码;

  • Douglas Crokford 的博客,http://www.crockford.com,提供了 Douglas 对 JavaScript 语言的研究课题,以及对一些经典问题的讨论;

  • JavaScript 教程:http://www.w3school.com.cn/js/index.asp,W3school 提供的 JavaScript 基础教程。

  • developerWorks Web development 专区:通过专门关于 Web 技术的文章和教程,扩展您在网站开发方面的技能。

  • developerWorks Ajax 资源中心:这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。

  • developerWorks Web 2.0 资源中心,这是有关 Web 2.0 相关信息的一站式中心,包括大量 Web 2.0 技术文章、教程、下载和相关技术资源。您还可以通过 Web 2.0 新手入门 栏目,迅速了解 Web 2.0 的相关概念。

讨论

My developerWorks 中文社区

转载于:https://www.cnblogs.com/asingna/archive/2011/09/28/2194516.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/475484.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Power BI 数据分析可视化软件入门教程

入 门 l Power BI 的引导学习 什么是Power BI&#xff1f; Power BI 是软件服务、应用和连接器的集合&#xff0c;它们协同工作以将相关数据来源转换为连贯的视觉逼真的交互式见解。 Power BI 简单且快速&#xff0c;能够从 Excel 电子表格或本地数据库创建快速见解。同…

分组统计 - DataFrame.groupby() 所见的各种用法 - Python代码

目录 所见 1 &#xff1a;日常用法 所见 2 &#xff1a;解决groupby.sum() 后层级索引levels上移的问题 所见 3 &#xff1a;解决groupby.apply() 后层级索引levels上移的问题 所见 4 &#xff1a;groupby函数的分组结果保存成DataFrame groupby的函数定义&#xff1a; Da…

LeetCode 1486. 数组异或操作

1. 题目 给你两个整数&#xff0c;n 和 start 。 数组 nums 定义为&#xff1a;nums[i] start 2*i&#xff08;下标从 0 开始&#xff09;且 n nums.length 。 请返回 nums 中所有元素按位异或&#xff08;XOR&#xff09;后得到的结果。 示例 1&#xff1a; 输入&#…

C 内存管理详解

程序员们经常编写内存管理程序&#xff0c;往往提心吊胆。如果不想触雷&#xff0c;唯一的解决办法就是发现所有潜伏的地雷并且排除它们&#xff0c;躲是躲不了的。本文的内容比一般教科书的要深入得多&#xff0c;读者需细心阅读&#xff0c;做到真正地通晓内存管理。   1、…

对照表 - 用心整理了一批国内省份、城市、县城的对照表,用于匹配,拿走不谢

采集的数据中&#xff0c;企业注册地址往往都是城市名&#xff0c;如果你想知道这些企业分布的省份&#xff0c;那么就需要这样一张对照表。 文件存储位置&#xff1a; 百度网盘链接: https://pan.baidu.com/s/1T8aobyzXRRvDQ0NjcEBCUw 提取码: cm7g 以下是文件中的前 100 …

js 获取url的get传值函数

最进在做瞎干项目时用到的&#xff0c;发上了备用&#xff0c;主要是用的正则匹配&#xff01; function getvl(name) {var reg new RegExp("(^|\\?|&)" name "([^&]*)(\\s|&|$)", "i");if (reg.test(location.href)) return unes…

LeetCode 1487. 保证文件名唯一(哈希map)

1. 题目 给你一个长度为 n 的字符串数组 names 。你将会在文件系统中创建 n 个文件夹&#xff1a;在第 i 分钟&#xff0c;新建名为 names[i] 的文件夹。 由于两个文件 不能 共享相同的文件名&#xff0c;因此如果新建文件夹使用的文件名已经被占用&#xff0c;系统会以 (k) …

线性回归 - 多元线性回归案例 - 分析步骤、输出结果详解、与Python的结果对比 -(SPSS建模)

现在用 Python 写线性回归的博客都快烂大街了&#xff0c;为什么还要用 SPSS 做线性回归呢&#xff1f;这就来说说 SPSS 存在的原因吧。 SPSS 是一个很强大的软件&#xff0c;不用编程&#xff0c;不用调参&#xff0c;点巴两下就出结果了&#xff0c;而且出来的大多是你想要的…

LeetCode 1488. 避免洪水泛滥(贪心+set二分查找)

1. 题目 你的国家有无数个湖泊&#xff0c;所有湖泊一开始都是空的。 当第 n 个湖泊下雨的时候&#xff0c;如果第 n 个湖泊是空的&#xff0c;那么它就会装满水&#xff0c;否则这个湖泊会发生洪水。 你的目标是避免任意一个湖泊发生洪水。 给你一个整数数组 rains &#xf…

R12 应付款模块(AP):预付款(prepayment)的标准处理流程

预付款的概念 财务会计的解释&#xff1a; 企业对于某些物资有时需要采取预先订购的方式&#xff0c;即按照购货合同规定预付一部分货款。这部分预先付给供货单位的订货款就构成了企业的预付账款。&#xff08;来自会计学概论&#xff0c;要区分定金和预付款的区别&#xff01;…

Python连接MySQL数据库(pymysql),DataFrame写入 MySQL(create_engine)- Python代码

模块安装 使用以下命令安装 PyMySQL&#xff1a; $ pip install PyMySQL 若系统不支持 pip&#xff0c;还可以这样安装&#xff1a; $ git clone https://github.com/PyMySQL/PyMySQL $ cd PyMySQL/ $ python3 setup.py install Python连接MySQL数据库 # -*- coding:utf-8…

LeetCode 391. 完美矩形(set检查顶点+面积检查)

1. 题目 我们有 N 个与坐标轴对齐的矩形, 其中 N > 0, 判断它们是否能精确地覆盖一个矩形区域。 每个矩形用左下角的点和右上角的点的坐标来表示。例如&#xff0c; 一个单位正方形可以表示为 [1,1,2,2]。 ( 左下角的点的坐标为 (1, 1) 以及右上角的点的坐标为 (2, 2) )。…

时间序列 - 案例按步骤详解 -(SPSS建模)

时间序列简单的说就是各时间点上形成的数值序列&#xff0c;通过观察历史数据的变化规律预测未来的值。在这里需要强调一点的是&#xff0c;时间序列分析并不是关于时间的回归&#xff0c;它主要是研究自身的变化规律的。 准备工作&#xff1a;SPSS - 中文版 SPSS 22.0 软件下…

正则表达式pcre在Android下的移植

因为项目需要在android的NDK开发中使用pcre正则表达式库&#xff0c;而android系统中并没有自带该库&#xff0c;所以就得另外移植了&#xff0c; 下面是移植的详细步骤&#xff1a; 1. 下载pcre源码&#xff0c;可以到http://sourceforge.net/projects/pcre/下载源码。 我这里…

LeetCode 593. 有效的正方形(数学)

1. 题目 给定二维空间中四点的坐标&#xff0c;返回四点是否可以构造一个正方形。 一个点的坐标&#xff08;x&#xff0c;y&#xff09;由一个有两个整数的整数数组表示。 示例: 输入: p1 [0,0], p2 [1,1], p3 [1,0], p4 [0,1] 输出: True注意: 所有输入整数都在 [-100…

特征计算 - 遍历求值提速 6 万倍 lambda...if...else(if...else...) +map() 对比 iterrows() - Python代码

Python 进行 DataFrame 数据处理的过程中&#xff0c;需要判断某一列中的值&#xff08;条件&#xff09;&#xff0c;然后对其他两列或三列进行求和&#xff08;均值/最值&#xff09;等运算&#xff0c;并把运算结果存储在新的一列中。干说可能觉得比较晕&#xff0c;我们来看…

写写最近吧,关于读研、找工作

刚刚又被朋友问到为什么要选择读研的问题了。已经好多好多人问过我这样的问题&#xff0c;我何尝不想问问自己到底为什么要读研呢。前段时间&#xff0c;每天在睡觉之前都我要想出无数个理由劝服自己要坚持读研&#xff0c;而每天早上第一件事又是再问自己为什么要读研。 我觉得…

非线性回归 - 案例按步骤详解 -(SPSS建模)

在上一篇时间序列的文章中&#xff0c;偶然发现另一份数据的整体趋势很符合非线性回归关系&#xff0c;那么就顺势写一篇非线性回归案例的文章吧。 准备工作&#xff1a;SPSS - 中文版 SPSS 22.0 软件下载与安装教程 - 【附产品授权许可码&#xff0c;永久免费】 数据解释&am…

LeetCode 609. 在系统中查找重复文件(哈希)

1. 题目 给定一个目录信息列表&#xff0c;包括目录路径&#xff0c;以及该目录中的所有包含内容的文件&#xff0c;您需要找到文件系统中的所有重复文件组的路径。 一组重复的文件至少包括二个具有完全相同内容的文件。 输入列表中的单个目录信息字符串的格式如下&#xff1…

邮件服务器之POP3协议分析

第1章. POP3概述 POP3全称为Post Office Protocol version3&#xff0c;即邮局协议第3版。它被用户代理用来邮件服务器取得邮件。POP3采用的也是C/S通信 模型&#xff0c;对应的RFC文 档为RFC1939。 该协议非常简单&#xff0c;所以我们只重点介绍其通信过程&#xff0c;而相关…