【翻译】Javascript最佳实践

Javascript最佳实践

介绍:
本文章是关于编写javascript代码一个最佳实践方法,基于javascript社区许多开发人员的意见和经验。这仅仅是一个建议,而不是一个绝对的规则,有经验的开发人员可能会略有不同的意见。


1. 使用'var'关键字

javascript中的变量会有全局作用域和函数级作用域。在申明变量的时候,无论是申明全局变量,还是函数内部变量,最好都带上‘var’关键字。下面这个例子会说明为什么要这么做。

不用var关键字产生的问题
-------------------------------
var i=0; // 这里没有问题 - 创建一个全局变量
function test() {
   for (i=0; i<10; i++) {
      alert("Hello World!");
   }
}
test();
alert(i); // 此时这里的i会变成10!
-------------------------------
由于for循环中的i没有使用var关键字,那么它会调用全局的那个i。使用var声明一个全局变量是个好主意,但是在函数体内部使用var申明变量是极其重要的。下面的两种方法在功能上是相同的。

修正后的函数
-------------------------------
function test() {
   for (var i=0; i<10; i++) {
      alert("Hello World!");
   }
}
-------------------------------

 

2. 特征检测优于浏览器检测

 有些javascript代码会基于代理来检测浏览器版本,并且采取不同的行动。这点,一般来说,是一个非常差的实践。任何代码中出现全局的“navigator”对象都是值得怀疑的。
 比较好的做法就是使用特征检测。当我们使用任何一个高级特征的时候,有些老版本的浏览器可能不支持这个特征。当我们要使用的时候,先检查一下,看看是否有这个函数或属性。下面这篇文章详细介绍了特征检测。http://www.jibbering.com/faq/faq_notes/not_browser_detect.html
 (译者注:也是英文的,但是推荐一读。这里作者写的很少,但是他想表达的意思是不要用类似navigator.userAgent,navigator.appName等关键字去检测浏览器版本,访问上面那个连接,相信大家会明白作者想表达的意思了。)

特征检测例子
-------------------------------
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来控制1,2,3。然后访问i=2的那个属性

正确做法:MyObject["value"+i]
错误做法:MyObject.value+i

一些服务器端(比如PHP,Struts等)会给表单的name属性传递一个"[]",表示这个表单元素将会传送一个数组到服务器端。
在这种带有"[]"的情况下用点“.”符号访问是行不通的,应该用方括号来访问。

正确做法:formref.elements["name[]"]
错误做法:formref.elements.name[]

到底是使用方括号还是使用点符号没有个明确规定,还是要看个人喜好。一个好的做法是使用点符号来访问标准属性的对象,使用方括号来访问页面中自定义的对象。比如document.getElementById()优先于document["getElementById"](),因为getElementById是document对象的一个标准属性。下面是混合使用方括号和点符号的例子:
document.forms["myformname"].elements["myinput"].value

在这里,forms属性是document的一个标准属性,myformname是表单自定义的一个属性。后面的elements,myinput,value同理。

 

4. 避免使用‘eval’
eval()函数可以在运行时中运行任何代码。在绝大多数情况下,eval不应该使用。如果它在你的页面中,确保它已经被正确的使用。
规则就是,“Eval是恶魔”。不要使用它,除非你是一个有经验的开发者,并且清楚你的例子是个例外。

 

5. 正确的使用Forms和Form元素
在HTML页面中表单需要有一个name属性。对于XHTML而言,name属性不是必须的,需要给表单一个id属性,然后通过document.getElementById()来访问。

使用索引值来获取表单,如document.forms[0],这通常是一个坏的实践。一些浏览器会使用表单的name属性来获取表单。

下面这个例子是正确引用表单中的input元素:

正确访问input
document.forms["formname"].elements["inputname"]
差的实践:document.formname.inputname

如果你要访问表单中多个元素,最好是先获取表单对象,把这个表单对象当做一个变量缓存起来。这样可以避免多次查找表单对象引用。
var formElements = document.forms["mainForm"].elements;
formElements["input1"].value="a";
formElements["input2"].value="b";

当需要通过onChange事件或其它类似事件来验证一个input控件时,一个好的做法是把input的自身引用对象传到函数里面。每个input控件都有一个form对象,这个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");
   }
}
-------------------------------
通过元素对象来访问表单对象,而不是通过表单的name属性来获取。这样的好处是这个函数可以被复用。

 

6. 避免使用‘with’
使用with语句时会在作用域链最顶端插入一个对象,因此访问任何一个属性或变量都将要先放问最顶端的那个对象。(译者注:关于作用域链的相关知识可以参考《高性能JavaScript》。当然此书同样值得推荐。)
使用with的例子:
-------------------------------
with (document.forms["mainForm"].elements) {
   input1.value = "junk";
   input2.value = "junk";
}
-------------------------------
这里会有个问题,程序员无法验证input1是否在elements数组中,如果没有找到input1,它会尝试在作用域链中去找。最后会一直找到全局的作用域链中。如果始终没有找到,就会报错。

正确的引用:
-------------------------------
var elements = document.forms["mainForm"].elements;
elements.input1.value = "junk";
elements.input2.value = "junk";
-------------------------------
(译者注:尽量少用with语句,最好不用,它会带来一些性能问题。)

 

7. 使用onclick属性来替换javascript:伪协议
当你想要在<A>标签中触发javascript代码的话,onclick句柄要比javascript:伪协议好。在onclick句柄上运行javascript代码,必须要返回一个true或false给标签本身。如果返回true,<A>标签的href属性将会继续执行。如果返回false,href属性将被忽略。(译者注:不是在函数体内部返回,而是紧跟着函数后面返回,如:<a href="
http://baidu.com" οnclick="ff(); return true;">click</a>)
这就是为什么要在onclick句柄后面跟一个“return false;”。

正确的使用:
<a href="javascript_required.html" οnclick="doSomething(); return false;">go</a>

有时,你想要一个有条件的跳转。举个例子,如果一个用户想要离开你的页面,你要先问下用户是否真的离开。如果用户不想离开页面就不跳转。
-------------------------------
<a href="/" onClick="return validate();">Home</a>

function validate() {
 return prompt("Are you sure you want to exit this page?");
}
-------------------------------
在这里,当我们点击A标签的时候,它将会返回一个true或false,这里是告知用户是否要离开当前页面。如果用户点击“是”,prompt()将返回true,那么href属性将被激活。反之不会。

下面是几个【错误】使用的例子,不要这么做,如果这么做了请尽快修改过来:
<a href="javascript:doSomething()">link</a>
<a href="#" onClick="doSomething()">link</a>
<a href="#" onClick="javascript:doSomething();">link</a>
<a href="#" onClick="javascript:doSomething(); return false;">link</a>

 

8. 使用“+”符号来转换数字
在javascript中,“+”操作符被用来做加法和连接字符串。这里会产生一个表单元素相加问题。举个例子,由于javascript是弱类型语言,表单中的元素值都会被认作字符串,如果你用“+”符号,那就是把他们当做字符串相加了。

问题举例:
<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); // This will alert "12", but what you wanted was 3!
}

想要修复这个问题,必须要把他们转化成数字。你可以使用“+”操作符,把字符串转成一个数字。把“+”符号放在一个表达式或变量前面,会把它强制转成一个数字。
修复后的代码:
-------------------------------
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是IE引进的,并不是DOM标准特性。尽管现在许多新的浏览器都支持这个属性,但是一些浏览器并不支持。
除非你确定你的程序一定是要用IE,不然的话就不要使用它。

能使用document.all的地方
-------------------------------
if (document.getElementById) {
 var obj = document.getElementById("myId");
}
else if (document.all) {
 var obj = document.all("myId");
}
-------------------------------
这里列出了一些使用document.all的规则:
·始终优先尝试使用其它的标准方法
·document.all当做最后手段时
·你需要支持比IE5.0更早的版本
·使用前始终做if检查“if (document.all) { }”

 

10. 在<script>标签块中不要使用HTML注释
早在1995年,一些浏览器如网景并不支持<script>标签。因此当javascript发布时,如果一些老的浏览器不支持javascript,可以使用HTML注释来隐藏它们。
<script language="javascript">
<!--
   // code here
//-->
</script>
现在的浏览器都已经支持javascript了,因此这种注释可以省略掉了。事实上,它可以被认为是有害的,原因如下:
·在XHTML文档中,源代码会被隐藏在所有浏览器中,那么注释将变得无用
·减减“--”在HTML注释中是不被允许的,因此任何减号操作在script中是没用的
(译者注:这句话原文是“-- is not allowed within HTML comments, so any decrement operations in script are invalid”,但是没弄懂这句话)


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
-------------------------------
命名空间通常会使用在闭包
功能里面,并且在模仿私有成员变量 也会用到。

 

12. 避免使用Ajax同步
当发出一个Ajax请求时,你可以选择同步或异步模式。异步模式在后台运行请求,同时浏览器可以执行其它操作。同步模式需要等待当前请求完毕后才能继续执行接下来的操作。

同步请求应当被避免。同步请求将会锁住用户的浏览器,直到请求结果返回。如果服务器繁忙,响应需要一段时间,那么用户的浏览器将无法继续做下面的事情。如果服务端一直没有响应,它会等到请求超时后才能继续工作。
如果你考虑要使用同步模式,那么请花点时间重新考虑下你的设计。在极少的情况下才会使用Ajax的同步模式。

 

13. 使用JSON
当我们在简单的文本中储存数据结构或者通过Ajax发送/接收数据结构时,如果可能的话,使用JSON来代替XML。JSON
是一个非常简洁和高效的数据格式,并且是一个中立语言。

 

14. 使用正确的<script>标签
<script>标签的LANGUAGE属性已经被废弃。可以这样正确的创建javascript代码块:
<script type="text/javascript">
// code here
</script>


 

原文地址:http://www.javascripttoolbox.com/bestpractices/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值