最佳JS代码编写的14条技巧


Posted in Javascript onJanuary 09, 2011

写任何编程代码,不同的开发者都会有不同的见解。但参考一下总是好的,下面是来自Javascript Toolbox发布的14条最佳JS代码编写技巧。

1. 总是使用 var

在javascript中,变量不是全局范围的就是函数范围的,使用var关键词将是保持变量简洁明了的关键。当声明一个或者是全局或者是函数级(function-level)的变量,需总是前置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; i10; i++) {
alert("Hello World!");
}
}

 正确的函数

  

function test() {
for (var i=0; i10; 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 表单被附加了 [ ] 号来表示 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 则是由页面所定义的。这页是句法让人非常容易理解(代码的内容),是一个推荐遵循的习惯用法,但不是严格原则。

4. 避免 eval

在Javascript中,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 元素数组的属性来解决。它首先以为这些名来检测属性,如果找不到,它将会继续(向下)检测这个作用域。最后,它在全局对象中尝试把input1 和 input2 作为一个全局对象来对待,而这以一个错误作为结尾。

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

使用一个引用:

var elements = document.forms["mainForm"].elements;

elements.input1.value = "junk";

elements.input2.value = "junk";

7. 在锚点中使用 onclick 替代 javascript: Pseudo-Protocol

如果你想在 a 标签中触发Javascript 代码,选择 onclick 而非 JavaScript: pseudo-protocol;使用 onclick 来运行的 Javascript 代码必须返回 ture 或者false(or an expression than evalues to true or false [这句要怎么翻译呢? 我是这样理解的:一个优先性高于true 或 false 的表达式])来返回标签本身:如果返回 true,则锚点的 href 将被当作一个一般的链接;如果返回 false,则 href 会被忽略。这就是为什么return false; 经常被包含在 onclick 所处理代码的尾部。

正确句法:

a href="javascript_required.html"go/a

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

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

有条件的链接访问:

a href="/"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="#"link/a

a href="#"link/a

a href="#"link/a

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中。

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>
Javascript 相关文章推荐
让 JavaScript 轻松支持函数重载 (Part 2 - 实现)
Aug 04 Javascript
innerHTML 和 getElementsByName 在IE下面的bug 的解决
Apr 09 Javascript
用js获取电脑信息(是使用与IE浏览器)
Jan 15 Javascript
javascript获得网页窗口实际大小的示例代码
Sep 21 Javascript
jquery插件开发之实现jquery手风琴功能分享
Mar 10 Javascript
JS组件Bootstrap按钮组与下拉按钮详解
May 10 Javascript
node.js实现快速截图
Aug 27 Javascript
jQuery实现动态添加tr到table的方法
Dec 26 Javascript
分享一道关于闭包、bind和this的面试题
Feb 20 Javascript
详解vue.js+UEditor集成 [前后端分离项目]
Jul 07 Javascript
解决VUE中document.body.scrollTop为0的问题
Sep 15 Javascript
Node.js API详解之 V8模块用法实例分析
Jun 05 Javascript
JavaScript定义类或函数的几种方式小结
Jan 09 #Javascript
javascript中用星号表示预录入内容的实现代码
Jan 08 #Javascript
js中访问html中iframe的文档对象的代码[IE6,IE7,IE8,FF]
Jan 08 #Javascript
js中top、clientTop、scrollTop、offsetTop的区别 文字详细说明版
Jan 08 #Javascript
Jquery Ajax请求代码(2)
Jan 07 #Javascript
JQuery 绑定select标签的onchange事件,弹出选择的值,并实现跳转、传参
Jan 06 #Javascript
神奇的7个jQuery 3D插件整理
Jan 06 #Javascript
You might like
第1次亲密接触PHP5(1)
2006/10/09 PHP
php实现的获取网站备案信息查询代码(360)
2013/09/23 PHP
PHP中捕获超时事件的方法实例
2015/02/12 PHP
CentOS 安装 PHP5.5+Redis+XDebug+Nginx+MySQL全纪录
2015/03/25 PHP
zend framework中使用memcache的方法
2016/03/04 PHP
php版微信公众平台之微信网页登陆授权示例
2016/09/23 PHP
Yii框架表单提交验证功能分析
2017/01/07 PHP
PHP函数用法详解【初始化、嵌套、内置函数等】
2020/06/02 PHP
基于jquery的一个浮动框(扩展性比较好 )
2010/08/27 Javascript
input 和 textarea 输入框最大文字限制的jquery插件
2011/10/27 Javascript
给jQuery方法添加回调函数一款插件的应用
2013/01/21 Javascript
js中for in语句的用法讲解
2015/04/24 Javascript
使用JavaScript脚本无法直接改变Asp.net中Checkbox控件的Enable属性的解决方法
2015/09/16 Javascript
jquery获取复选框checkbox的值的简单实现方法
2016/05/26 Javascript
微信小程序 window_x64环境搭建
2016/09/30 Javascript
基于vue中解决v-for使用报红并出现警告的问题
2018/03/03 Javascript
Vue.js下拉菜单组件使用方法详解
2019/10/19 Javascript
微信小程序实现注册登录功能(表单校验、错误提示)
2019/12/10 Javascript
Python实现并行抓取整站40万条房价数据(可更换抓取城市)
2016/12/14 Python
python删除文件夹下相同文件和无法打开的图片
2019/07/16 Python
flask框架jinja2模板与模板继承实例分析
2019/08/01 Python
Python用来做Web开发的优势有哪些
2020/08/05 Python
关于探究python中sys.argv时遇到的问题详解
2021/02/23 Python
什么是数据抽象
2016/11/26 面试题
工程管理专业个人求职信范文
2013/12/07 职场文书
创意广告词
2014/03/17 职场文书
司仪主持词两篇
2014/03/22 职场文书
竞选班委演讲稿
2014/04/28 职场文书
治超工作实施方案
2014/05/04 职场文书
应届硕士毕业生自荐信
2014/05/26 职场文书
销售目标责任书
2014/07/23 职场文书
我是一名护士演讲稿
2014/08/28 职场文书
污染环境建议书
2015/09/14 职场文书
如何拟写通知正文?
2019/04/02 职场文书
CSS实现隐藏搜索框功能(动画正反向序列)
2021/07/21 HTML / CSS
tomcat正常启动但网页却无法访问的几种解决方法
2022/05/06 Servers