Javascript最佳实践

1. 使用===,而不是==

==(或!=)操作符在需要的时候会自动执行类型转换。===(或!==)操作不会执行任何转换。它将比较值和类型,而且在速度上也被认为优于==。

1
2
3
4
5
6
7
8
[10] === 10    // false
[10] == 10 // true
'10' == 10 // true
'10' === 10 // false
[] == 0 // true
[] === 0 // false
'' == false // true but true == "a" is false
'' === false // false

2. 使用闭包实现私有成员

1
2
3
4
5
6
7
8
9
function Person() {
var occupation;
this.getOccupation = function() {
return occupation;
};
this.setOccupation = function(newOcc) {
occupation = newOcc;
};
}

3. 使用自调用函数(Self-calling Funtion)

这个经常被称为自调用匿名函数(Self-Invoked Anonymous Function)或者即时调用函数表达式(IIFE-Immediately Invoked Function Expression)。这是一个在创建后立即自动执行的函数,通常如下:

1
2
3
4
(function(a,b){
var result = a+b;
return result;
})(10,20)

4. 使用逻辑 AND/OR 做条件判断

1
2
3
var foo = 10;
foo == 10 && doSomething(); // 等价于 if (foo == 10) doSomething();
foo == 5 || doSomething(); // 等价于 if (foo != 5) doSomething();

逻辑 AND 还可以被使用来为函数参数设置默认值:

1
2
3
function doSomething(arg1){
Arg1 = arg1 || 10; // 如果arg1没有被设置的话,Arg1将被默认设成10
}

5. 逗号操作符

1
2
3
4
var a = 0;
var b = ( a++, 99 );
console.log(a); // a will be equal to 1
console.log(b); // b is equal to 99

6. 在调用 isFinite()之前验证参数

1
2
3
4
5
6
7
isFinite(0/0) ; // false
isFinite("foo"); // false
isFinite("10"); // true
isFinite(10); // true
isFinite(undifined); // false
isFinite(); // false
isFinite(null); // true !!!

7. JSON的序列化和反序列化(serialization and deserialization)

1
2
3
4
5
var person = {name :'Saad', age : 26, department : {ID : 15, name : "R&D"} };
var stringFromPerson = JSON.stringify(person);
/* stringFromPerson is equal to "{"name":"Saad","age":26,"department":{"ID":15,"name":"R&D"}}" */
var personFromString = JSON.parse(stringFromPerson);
/* personFromString is equal to person object */

8. 避免使用 eval() 和 Function 构造函数

使用 eval 和 Function 构造函数是非常昂贵的操作,因为每次他们都会调用脚本引擎将源代码转换成可执行代码。

1
2
var func1 = new Function(functionCode);
var func2 = eval(functionCode);

同理,setTimeout() 和 setInterval() 的时候传入函数,而不是字符串,因为如果你将字符串传递给 setTimeout() 或者 setInterval(),这个字符串将被如使用 eval 一样被解析,这个是非常耗时的。

1
2
3
4
5
6
7
// bad
setInterval('fun()', 1000);
setTimeOut('fun()', 5000);

//good
setInterval(fun, 1000);
setTimeOut(fun, 5000);

9. 避免使用 for-in 来遍历一个数组

1
2
3
4
5
6
7
8
9
10
11
// bad
var sum = 0;
for (var i in arrayNumbers) {
sum += arrayNumbers[i];
}

//good
var sum = 0;
for (var i = 0, len = arrayNumbers.length; i < len; i++) {
sum += arrayNumbers[i];
}

10. 避免在循环内部使用 try-catch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// bad
var object = ['foo', 'bar'], i;
for (i = 0, len = object.length; i <len; i++) {
try {
// do something that throws an exception
}
catch (e) {
// handle exception
}
}

//good
var object = ['foo', 'bar'], i;
try {
for (i = 0, len = object.length; i <len; i++) {
// do something that throws an exception
}
}
catch (e) {
// handle exception
}

11. 为 XMLHttpRequest 设置超时

在一个XHR请求占用很长时间后(比如由于网络问题),你可能需要中止这次请求,那么你可以对XHR调用配套使用 setTimeout():

1
2
3
4
5
6
7
8
9
10
11
12
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
clearTimeout(timeout);
// do something with response data
}
}
var timeout = setTimeout( function () {
xhr.abort(); // call error callback
}, 60 * 1000);
xhr.open('GET', url, true);
xhr.send();

此外,一般应该完全避免同步的Ajax请求。

12. 为 WebSocket 设置超时

通常,在一个WebSocket连接创建之后,如果你没有活动的话,服务器会在30秒之后断开(time out)你的连接。防火墙也会在一段时间不活动之后断开连接。
为了防止超时的问题,你可能需要间歇性地向服务器端发送空消息。要这样做的话,你可以在你的代码里添加下面的两个函数:一个用来保持连接,另一个用来取消连接的保持。通过这个技巧,你可以控制超时的问题。
使用一个 timerID:

1
2
3
4
5
6
7
8
9
10
11
12
13
var timer = 0;
function keepAlive() {
var timeout = 15000;
if (webSocket.readyState == webSocket.OPEN) {
webSocket.send('');
}
timer = setTimeout(keepAlive, timeout);
}
function cancelKeepAlive() {
if (timer) {
cancelTimeout(timer); //为什么不是clearTimeout()
}
}

13. 原始运算符始终比函数调用要高效

1
2
3
4
5
6
7
// bad
var min = Math.min(a,b);
A.push(v);

// good
var min = a < b ? a : b;
A[A.length] = v;

14. 发布的时候不要忘记使用代码压缩工具

在发布之前使用JSLint和代码压缩工具(minification)(比如JSMin)。

感谢您的阅读,有不足之处请在评论为我指出!

参考资料

[1]:45个实用的JavaScript技巧、窍门和最佳实践

版权声明:本文为博主原创文章,未经博主允许不得转载。本文地址 http://yangyuji.github.io/2015/07/31/javascript-best-practices/