JavaScript 编程最佳实践:14 条核心编码规范

作者:纸飞机

时间:2026-10-30

浏览:121

本文总结了编写 JavaScript 代码时应遵循的 14 条核心规律。内容涵盖变量声明、特性检测、DOM 访问、表单处理、作用域管理及异步请求等关键领域,旨在帮助开发者提升代码质量、可维护性及兼容性,避免常见陷阱。

文章目录

JavaScript 编码规范概述

本文总结了编写 JavaScript 代码时应遵循的 14 条核心规律,旨在为开发者提供实用的参考建议。

变量声明与作用域管理

1. 始终使用 'var' 声明变量

在 JavaScript 中,变量作用域仅限于全局或函数级别。使用 'var' 关键字是保持变量清晰可控的关键。在声明全局或函数级变量时,务必前置 'var' 关键词,否则可能引发潜在问题,如下例所示。

未使用 Var 导致的潜在问题


var i=0; // This is good - creates a global variable
function test() {
for (i=0; i<10; i++) {
alert("Hello World!");
}
}
test();
alert(i); // The global variable i is now 10!

若变量 i 在函数中未使用 'var' 声明,它将引用全局变量。虽然声明全局变量时总是使用 'var' 是常见做法,但至关重要的一点是使用 'var' 来定义函数作用域的变量。以下两个方法在功能上等效:

正确的函数定义方式


function test() {
var i=0;
for (i=0;i<10; i++) {
alert("Hello World!");
}
}

正确的函数定义方式


function test() {
for (var i=0; i<10; i++) {
alert("Hello World!");
}
}

特性检测与浏览器兼容性

2. 采用特性检测而非浏览器检测

部分代码旨在识别浏览器版本并基于客户端执行不同行为,这通常被视为不良实践。更优的方法是进行特性检测:在使用老浏览器可能不支持的高级特性前,先检测该特性是否存在。这比单独检测浏览器版本更为可靠,即使你已知其性能表现。关于此问题的深入讨论可参考相关技术文章。

示例代码


if (document.getElementById) {
var element = document.getElementById('MyId');
} else {
alert('Your browser lacks the capabilities required to run this script!');
}

对象属性访问与方括号记法

3. 使用方括号记法访问属性

当访问由执行时决定的属性,或属性名包含无法通过 '.' 符号访问的字符时,应使用方括号记法。对于非资深 JavaScript 程序员而言,始终使用方括号是一种良好的习惯。

对象属性主要有两种访问方式:'.' 记法和 '[ ]' 方括号记法:

'.' 号记法示例


MyObject.property

'[ ]' 方括号记法示例


MyObject["property"]

使用 '.' 号时,属性名是硬编码的,无法在执行时动态改变。而使用 '[ ]' 方括号时,属性名是一个计算得出的字符串,该字符串可以是硬编码的,也可以是变量,甚至是返回字符串值的函数。若属性名在执行时动态生成,必须使用方括号。例如,若有 'value1'、'value2' 和 'value3' 属性,且想利用变量 i=2 来访问,则需使用方括号。

可行的代码示例


MyObject["value"+i]

不可行的代码示例


MyObject.value+i

此外,在某些服务器端环境(如 PHP、Struts 等)中,Form 表单字段常附加 '[ ]' 号以表示服务器端需将其视为数组。此时,若使用 '.' 号引用包含 '[ ]' 的字段将无法执行,因为 '[ ]' 是引用 JavaScript 数组的语法。因此,必须使用 '[ ]' 记法:

可行的代码示例


formref.elements["name[]"]

不可行的代码示例


formref.elements.name[]

推荐使用 '[ ]' 方括号记法的建议是:在必要时(明显需要时)始终使用它。当非严格需要时,这属于个人偏好和习惯。一个好的经验法则是:使用 '.' 号记法访问标准对象属性,使用 '[ ]' 方括号记法访问由页面定义的对象属性。例如,document["getElementById"]() 是完全可行的方括号用法,但 document.getElementById() 在语法上更受青睐,因为 getElementById 是 DOM 规范中定义的标准文档对象属性。混合使用这两种记法能使代码清晰明了,区分哪些是标准对象属性,哪些是由上下文定义的属性名:


document.forms["myformname"].elements["myinput"].value

在此例中,forms 是 document 的标准属性,而表单名 myformname 则由页面定义。同时,elements 和 value 属性均由规范定义的标准属性,而 myinput 则由页面定义。这种写法在语法上易于理解(代码内容),是一种推荐遵循的习惯用法,但并非严格原则。

避免使用 eval 与 with

4. 避免使用 'eval'

在 JavaScript 中,eval() 函数用于在执行期执行任意代码。在几乎所有情况下,都不应使用 eval。若你的页面中出现了 eval,说明你采用的方法并非最优。例如,eval 常被不了解方括号记法的程序员误用。

原则上,'Eval is evil(Eval 是魔鬼)'。除非你是经验丰富的开发者且确信你的情况属于例外,否则请勿使用它。

表单与表单元素的正确引用

5. 正确引用表单及表单元素

所有 HTML 表单都应包含 name 属性。对于 XHTML 文档,虽不强制要求 name 属性,但 Form 标签中应包含相应的 id 属性,并必须使用 document.getElementById() 来引用。使用如 document.forms[0] 这样的索引方法来引用表单,在几乎所有情况下都是不良实践。部分浏览器会将文档中使用 form 命名的元素视为可用的 form 属性,但这并不可靠,不应使用。

以下示例展示了如何使用方括号和正确的对象引用方法来防止错误地引用表单的 input:

正确引用表单 Input


document.forms["formname"].elements["inputname"]

糟糕的做法示例


document.formname.inputname

若需引用函数中的两个表单元素,较好的做法是先引用该 form 对象,并将其存储在变量中。这样可以避免重复查询以解决表单的引用问题:


var formElements = document.forms["mainForm"].elements;
formElements["input1"].value="a";
formElements["input2"].value="b";

当你使用 onChange 或其他类似的事件处理方法时,一个好的做法是总是通过一个引用来将 input 元素本身传递到函数中。所有 input 元素都包含一个对其所在 Form 表单的引用:


<input type="text" name="address" onChange="validate(this)">

function validate(input_obj) {  // 引用包含这个元素的form
var theform = input_obj.form;  // 现在你可以不需要使用硬代码来引用表单自身
if (theform.elements["city"].value=="") {
alert("Error");
}
}

通过对表单元素的引用来访问表单的属性,你可以编写一个不包含硬编码的函数来引用页面中任何具有特定名称的表单。这是一种非常好的做法,因为函数变得可重用。

6. 避免使用 'with'

JavaScript 中的 with 声明在作用域前端插入了一个对象,因此任何属性/变量的引用将首先依据该对象解析。这通常被用作避免重复引用的快捷方式:

使用 with 的示例


with (document.forms["mainForm"].elements) {
input1.value = "junk";
input2.value = "junk";
}

但问题在于程序员无法验证 input1 或 input2 实际上已被作为 Form 元素数组的属性解析。它会首先检测这些 name 值的属性,若找不到,将继续向下检测该作用域。最后,它尝试在全局对象中将 input1 和 input2 视为全局对象,这将导致错误。

变通方法是:创建一个引用来减少引用的对象,并使用它来解析这些引用。

使用一个引用的示例


var elements = document.forms["mainForm"].elements;
elements.input1.value = "junk";
elements.input2.value = "junk";

锚点事件处理与链接控制

7. 在锚点中使用 'onclick' 替代 'javascript:' 伪协议

若想在 <a> 标签中触发 JavaScript 代码,应选择 onclick 而非 JavaScript: 伪协议;使用 onclick 运行的 JavaScript 代码必须返回 true 或 false(或一个求值为 true 或 false 的表达式)来返回标签本身:如果返回 true,则锚点的 href 将被视为普通链接;如果返回 false,则 href 会被忽略。这就是为什么 'return false;' 经常包含在 onclick 处理代码的尾部。

正确语法示例

代码如下

<a href="https://www.jb51.net" onclick="doSomething(); return false;">go</a>

在此实例中,'doSomething()' 函数(定义于页面的某个角落)将在被点击时调用。href 将永远不会被启用了 JavaScript 的浏览器访问。在你可以提醒 JavaScript 是必须的、而用户未启用之的浏览器中,文档 javascript_required.html 才会被加载。通常,当你确保用户将开启 JavaScript 支持时,为尽量简化,链接将只包含 href="#"。而这个做法是不被鼓励的。通常有一个不错的做法是:可以提供没用启用 javascript 一个返回本地的页面。

有时,众多想要分情况来访问一个链接。例如,当一个用户要离开你的一个表单页面,而想先验证来确保没有东西被改变。在这个情况下,你的 onclick 将会访问一个返回询问链接是否应该被遵循的函数:

有条件的链接访问示例


<a href="/" onClick="return validate();">Home</a>


function validate() {
return prompt("Are you sure you want to exit this page?");
}

在此实例中,validate() 函数必须只返回 ture 或 false。ture 的时候用户将被允许问题 home 页面,或 false 的时候链接不被访问。这个例子提示确认(其行为),以访问 ture 或 false,这完全由用户点击”确实”或者”取消”决定。

下面是一些”不应该”的例子。如果你在自己的页面中看到下面这样的代码,这是不正确的,需要被修改:

什么是不应该做的示例


<a href="javascript:doSomething()">link</a>
<a href="https://www.jb51.net/#" onClick="doSomething()">link</a>
<a href="https://www.jb51.net/#" onClick="javascript:doSomething();">link</a>
<a href="https://www.jb51.net/#" onClick="javascript:doSomething(); return false;">link</a>

数据类型转换与 DOM 访问

8. 使用一元 '+' 号运算符使类型转向 Number

在 JavaScript 中,'+' 号运算符同时充当数学加号和连接符。这会在 form 表单的域值相加时出现问题,例如,因为 JavaScript 是一个弱类型语言,form 域的值将会被当作数组来处理,而你把它们 '+' 一起的时候,'+' 将被当成连接符,而非数学加号。

有问题的示例


<form name="myform" action="[url]">
<input type="text" name="val1" value="1">
<input type="text" name="val2" value="2">
</form>


function total() {
var theform = document.forms["myform"];
var total = theform.elements["val1"].value + theform.elements["val2"].value;
alert(total); // 这个将会弹出 "12", 但你想要的是 3!
}

解决这个问题,JavaScript 需要一个提示来让它把这些值当做数字来处理。你可以使用 '+' 号来把数组转换成数字。给变量或者表达式前置一个 '+' 号将会强制其当作一个数字来处理,而这也将使得数学 '+' 得以成功应用。

修改好的代码示例


function total() {
var theform = document.forms["myform"];
var total = (+theform.elements["val1"].value) + (+theform.elements["val2"].value);
alert(total); // This will alert 3
}

9. 避免使用 document.all

document.all 是由 Microsoft 的 IE 所引进的,并不是一个标准的 JavaScript DOM 特性。尽管大多数新的浏览器支持它以支持依赖于它的糟糕代码,(而)还有很多浏览器是不支持的。

并没有理由其他方法都不适用,而一个老的 IE 浏览器(<5.0)需要支持,而在 JavaScript 中使用 document.all 作为一个折衷方法。你并不需要使用 document.all 来检测其是不是 IE 浏览器,因为其他浏览器现在一般都支持。

只把 document.all 当做最后的选择


if (document.getElementById) {
var obj = document.getElementById("myId");
} else if (document.all) {
var obj = document.all("myId");
}

一些使用 document.all 的原则

同尝试其他方法 当其作为最后的选择 当需要支持 5.0 版本以下的 IE 浏览器 总是使用 “if (document.all) { }” 来查看是否支持.

脚本标签规范与命名空间

10. 不要在脚本代码块中使用 HTML 注释

在 JavaScript 的旧日子(1995)里,诸如 Netscape 1.0 的一些浏览器并不支持或认识 <script> 标签。所以,当 JavaScript 第一次被发布,需要有一个技术来让实些代码不被当做文本显示于旧版浏览器上。有一个 'hack' 是在代码中使用 HTML 注释来隐藏这些代码。

使 HTML 注释并不好


<script language="javascript">
<!--  // code here //-->
</script>

在今天,没有任何一个常用的浏览器会忽略掉 <script> 标签。因此,再没必要隐藏 JavaScript 源代码。事实上,它还可以因为下面的理由,被认为是无益的:

在 XHTML 文档中,源代码将向所有浏览器隐藏并被渲染成无用的(内容);

– 在 HTML 注释并不允许 ,这个会让任何递减操作将失效。

11. 避免乱用全局命名空间

一般很少需要全部变量和函数。全局使用将可能导致 JavaScript 源文件文档冲突,和代码中止。因此,一个好的做法是在一个全局命名空间内采用函数性的封装。有多个方法可以完成这个任务,有此相对比较复杂。最简单的方法 是创建一个全局对象,并把属性和方法指派给这个对象:

创建一个命名空间示例


var MyLib = {}; // global Object cointainer
MyLib.value = 1;
MyLib.increment = function() {
MyLib.value++;
}
MyLib.show = function() {
alert(MyLib.value);
}
MyLib.value=6;
MyLib.increment();
MyLib.show(); // alerts 7

命名空间也可以使用 Closures(闭包?) 来创建,并且 Private Member Variables (私有变量?) 也可以伪装于 Javascript 中。

Ajax 调用与数据格式选择

12. 避免同步的 'ajax' 调用

当使用 'Ajax' 请求时,你要么选择异步模式,要么使用同步模式。当浏览器行为可以继续执行,异步模式将请求放在后台执行,同步模式则会等待请求完成后才继续。

应该避免同步模式做出的请求。这些请求将会对用户禁用浏览器,直至请求返回。一旦服务器忙,并需要一段时间来完成请求,用户的浏览器(或者 OS)将不能做任何其他的事,直至请求超时。

如果你觉得自己的情况需要同步模式,最大的可能是你需要时间来重新想一下你的设计。很少(如果有的话)实际上需要同步模式的 Ajax 请求。

13. 使用 JSON

当需要将数据结构存储成纯文本,或者通过 Ajax 发送/取回数据结构,尽可能使用 JSON 代替 XML。JSON (JavaScript Object Notation) 是一个更简洁有效的数据存储格式,并且不依赖任何语言(and is a language-neutral)。

14. 使用正确的 <script> 标签

不赞成在 <script> 中的使用 LANGUAGE 属性。一个合适的方式是创建如下的 JavaScript 代码块:


<script type="text/javascript">
// code here
</script>

PS:上述代码没有经过格式化处理,通常格式化处理后的代码会比较容易阅读理解,小编这里就为大家推荐几款在线格式化与压缩工具,方便大家在今后的开发中使用:

在线 JavaScript 代码美化、格式化工具: http://tools.jb51.net/code/js

JavaScript 代码美化/压缩/格式化/加密工具: http://tools.jb51.net/code/jscompress

jsmin 在线 js 压缩工具: http://tools.jb51.net/code/jsmincompress

json 代码在线格式化/美化/压缩/编辑/转换工具: http://tools.jb51.net/code/jsoncodeformat

更多关于 JavaScript 相关内容感兴趣的读者可查看本站专题:《JavaScript 切换特效与技巧总结》、《JavaScript 查找算法技巧总结》、《JavaScript 动画特效与技巧汇总》、《JavaScript 错误与调试技巧总结》、《JavaScript 数据结构与算法技巧总结》、《JavaScript 遍历算法与技巧总结》及《JavaScript 数学运算用法总结》

希望本文所述对大家 JavaScript 程序设计有所帮助。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章