1. 不使用script自闭合标签
script中使用自闭合标签,虽然他在XHTML中合法,但是不符合HTML规范,而且得不到某些浏览器的正确解析。我曾经就在引入EXT时使用此方式,导致无法正确执行脚本。
<script src="example.js"/> --> <script src="example.js"></script>
2. 将脚本放到</body>前面
如果将脚本文件放到<head>中去,则在显示页面前先得下载执行脚本,增加了用户等待的时间。样式表放在<head>中防止内容显示不正常。一般方式如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" type="text/css" href="theme.css" /> </head> <body> <!-- html代码 --> <script src="example.js"/> </body> </html>
3. 在函数内使用严格模式
如果在函数外部使用严格模式,则有可能会使第三方类库,和同事的代码不能正常工作,在函数内部则只能影响自己的代码,不至于影响到别人的代码。
function myfunction(){ "use strict"; //函数代码 }
4. 不要省略语句结尾的分号
代码结尾处没有分号容易引起压缩错误,另外在某些情况下可以增进代码的性能,应为解释器不比在花时间推测在什么地方插入分号。还有一种更常见的问题就是,自动插入分号有时会出错,所以并不建议省略分号。
5. 使用var定义变量
定义变量时使用var关键字,并且全部提前至函数的最开始。
这样做的好处就会避免无意识的创建出全局变量,而且让你的代码更容易理解。
function myfunction(){ var result = 10 + value; var value = 10; return result; }
这个函数语法上是没有问题的,但是不是很直观,不符合人的逻辑,修改如下会更好:
funciton myfunction(){ var result; var value; result = 10 + value; value = 10; return result; }
给大家解释一下,上面两个代码是等价的,result的值都是NAN.JavaScript会把函数内所有的变量声明提升到函数的最开始,代码一在代码执行时会变成代码二的样子,当运行到result = 10 + value;时,value的值为undefined,和10相加为NAN,然后value被赋值为10。
关于全局变量带来的问题,大家想必也比较清楚,不然也不会出现命名空间的概念。
6. 函数先声明再使用
和变量声明一样,函数声明也会被JavaScript引擎提前,因此在代码中,函数的调用可以出现在函数的声明之前。 还有一点值得注意,函数声明不应该出现在语句块之内,比如:
if (condition) { function myfunction(){ alert("true"); } }else{ function myfunction(){ alert("false"); } } myfunction();
运行代码我们发现会输出会和浏览器有关,在Chrome 51和Firefox 46输出true,IE 10下输出false。所以尽量避免在语句块中声明函数。
7. 慎用typeof underfined null判断
null是一个特殊值,我们经常和undefined混淆,下列场景应使用null:
用来初始化一个变量,这个变量可能赋值为一个对象。
用来和一个已经初始化的变量比较。
当函数的参数期望传入对象时,用作参数传入。
当函数的返回值期望是对象时,用作返回值传出。
下面一些情况不应该使用null:
不要使用null来检查是否传入了某个参数。
不要用null来检查一个变量是不是初始化。
理解null最好的方式是将他当做对象的占位符。我们经常将null和undefined搞混的原因是我们认为null和undefined都是变量未初始化,但是只有undefin代表一个变量还没有被初始化,null代表初始化为对象。看如下代码:
var person; console.log(typeof person); //undefined console.log(typeof foo); //undefined var house = null; console.log(typeof house); //object
所以尽量不要用typeof判断变量是否初始化,你并不能确定是变量不存在还是变量未初始化,返回null是你也不能确定变量有没有被正确的赋值,所以小心使用typeof。
8. 小心使用Number类型
想必大家也知道JavaScript整数支持十进制,八进制,和十六进制的字面值。八进制中如果字面值中的数值超过了范围,那么前导零将会被忽略,后面的数值当做十进制解析。
console.log(012); //10
console.lgo(082); //82
如果将八进制和十六进制用于小数则会语法错误。还有一点,八进制字面量在严格模式下是无效的。 关于浮点数计算误差的问题大家也都清楚,凡是基于IEEE754数值的浮点计算都是这样,所以永远不要测试某个特定的浮点数值。
在数值类型中有一个比较特殊的值,NaN(Not a Number),这个数值用于表示本来应该返回数值但是返回的不是数值类型。NaN和任何值都不相等,包括NaN本身。我们可以用isNaN()函数测试。
9. 使用逻辑运算动态赋值
大家比较喜欢的操作
var person={ age:10 } var condition; var myVar = condition && person; alert(myVar)
如果condition转为boolean类型为false,则myVar = condition,若为true,则myVar = person。
var person={ age:10 } var condition; var myVar = condition || person; alert(myVar)
如果condition转换为boolean为true,则myVar = condition,若为false,则myVar = person。
10. 不使用with语句
不使用with的一个重要原因是,在严格模式下语法本身就是禁用with语句的,这也表明ECMAScript委员会确信不应使用with。我们看如下例子:
var book = { title : "Maintainable JavaScript", author: "Nicholas C. Zakas" }; var message = "The book is "; with(book) { message += title; message += "by " + author; }
上述代码的问题在于我们很难分辨title和author出现的位置,也难分辨出message到地址一个局部变量还是book的一个属性,而且JavaScript引擎和压缩工具无法对这段代码进行优化,应为它们无法猜出代码的正确含义。
好了,已经十条了,我们下一个十条再见。