在这篇文章中,我将分享一些JavaScript常用的技巧,窍门和最佳实践。不管JavaScript开发者是使用在浏览器/引擎上或者服务器端(SSJS——Service Side JavaScript)JavaScript解释器上,这些他们都是应该知晓的。
需要注意的是,文章中的代码片段均是在最新的Google Chrome(版本号30)上测试过,它使用V8 JavaScript引擎(V8 3.20.17.15)。
1、第一个给变量分配值时不要忘了var关键字。
分配值给未定义的变量将是该变量自动成为全局变量,应该避免全局变量。
2、使用===而不是==
==(或!=)操作符在需要时会自动转换变量类型,而===(或!==)则不会执行类型转换。在进行值和类型比较的时候,应首先考虑使用===
[10] === 10 // is false
[10] == 10 // is true
'10' == 10 // is true
'10' === 10 // is false
[] == 0 // is true
[] === 0 // is false
'' == false // is true but true == "a" is false
'' === false // is false
3、undefined、null、0、false、NaN、’’(空字符串)都被视为false。
4、在行尾使用分号
在行尾使用分号是很好的实践。如果你忘了,也不会得到警告,因为大多数情况下JavaScript解释器会插入分号的。更多关于你为什么要使用分号的细节,可以看看此文:http://davidwalsh.name/javascript-semicolons.
5、创建对象构造函数
function Person(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
}
var Saad = new Person("Saad", "Mousliki");
6、小心使用typeof、instanceof和constructor
typeof:不要忘了typeof null返回object,而大多数对象,typeof(Array, Date, and others)也将返回object
constructor:内部原型属性,可以被覆盖(可以参考:又谈原型对象)
instanceof:JavaScript的一个用于检查构造函数的原型链的操作符
var arr = ["a", "b", "c"];
typeof arr; // return "object"
arr instanceof Array // true
arr.constructor(); //[]
7、创建一个自执行函数
这个经常被称为自我调用的匿名函数或者立即调用的函数表达式(IIFE)。当你创建它时,它会自动执行的函数。
(function(){
// some private code that will be executed automatically
})();
(function(a,b){
var result = a+b;
return result;
})(10,20)
8、随机获取一个数组项
var items = [12, 548 , 'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' , 2145 , 119];
var randomItem = items[Math.floor(Math.random() * items.length)];
9、在特定范围内获取一个随机数
x = Math.floor(Math.random() * (max - min + 1)) + min;
10、从数字0到最大值之间获取一个数字数组
var numbersArray = [] , max = 100;
for( var i=1; numbersArray.push(i++) < max;); // numbers = [0,1,2,3 ... 100]
11、生成一个随机字符串
function generateRandomAlphaNum(len) {
var rdmstring = "";
for( ; rdmString.length < len; rdmString += Math.random().toString(36).substr(2));
return rdmString.substr(0, len);
}
12、打乱一个数字数组的元素顺序
var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
numbers = numbers.sort(function(){ return Math.random() – 0.5});
/* the array numbers will be equal for example to
[120, 5, 228, -215, 400, 458, -85411, 122205] */
13、String的trim函数
String.prototype.trim = function(){return this.replace(/^\s+|\s+$/g, "");};
14、将一个数组附加到另一个数组
var array1 = [12 , "foo" , {name: "Joe"} , -2458];
var array2 = ["Doe" , 555 , 100];
Array.prototype.push.apply(array1, array2);
/* array1 will be equal to [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */
15、将arguments对象转换成一个数组
var argArray = Array.prototype.slice.call(arguments);
16、验证参数是否是number类型
function isNumber(n){
return !isNaN(parseFloat(n)) && isFinite(n);
}
17、验证参数是否是数组
function isArray(obj){
return Object.prototype.toString.call(obj) === '[object Array]' ;
}
注意,toString()方法被重写,使用这个技巧将得不到期望的结果了。或者可以这样:
Array.isArray(obj); // 这是一个新的array的方法
如果你不在使用多重frames的情况下,你还可以使用 instanceof 方法。但如果你有多个上下文,你就会得到错误的结果。
var myFrame = document.createElement('iframe');
document.body.appendChild(myFrame);
var myArray = window.frames[window.frames.length-1].Array;
var arr = new myArray(a,b,10); // [a,b,10]
// instanceof will not work correctly, myArray loses his constructor
// constructor is not shared between frames
arr instanceof Array; // false
18、获取数字数组中的最大值和最小值
var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
var maxInNumbers = Math.max.apply(Math, numbers);
var minInNumbers = Math.min.apply(Math, numbers);
19、清空一个数组
var myArray = [12 , 222 , 1000 ];
myArray.length = 0; // myArray will be equal to [].
20、不要使用delete去删除一个数组项
使用 split 而不要使用 delte 来删除数组中的某个项。使用 delete 只是用 undefined 来替换掉原有的项,并不是真正的从数组中删除。不要用如下的方式
var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];
items.length; // return 11
delete items[3]; // return true
items.length; // return 11
/* items will be equal to [12, 548, "a", undefined × 1, 5478,
"foo", 8852, undefined × 1, "Doe", 2154, 119] */
而是用下列的方式
var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];
items.length; // return 11
items.splice(3,1) ;
items.length; // return 10
/* items will be equal to [12, 548, "a", 5478,
"foo", 8852, undefined × 1, "Doe", 2154,119] */
应该用delete来删除一个对象的属性
21、使用 length 来截短一个数组
跟上面的清空数组的方式类似,我们使用 length 属性来截短一个数组。
var myArray = [12 , 222 , 1000 , 124 , 98 , 10 ];
myArray.length = 4; // myArray will be equal to [12 , 222 , 1000 , 124].
此外,如果你将一个数组的 length 设置成一个比现在大的值,那么这个数组的长度就会被改变,会增加新的 undefined 的项补上。 数组的 length 属性是可读写的。
myArray.length = 10; // the new array length is 10
myArray[myArray.length - 1] ; // undefined
22、在条件中使用逻辑运算符:AND、OR
var foo = 10;
foo == 10 && doSomething(); // 等价于 if (foo == 10) doSomething();
foo == 5 || doSomething(); // 等价于 if (foo != 5) doSomething();
OR可以用于给函数设置默认参数
function doSomething(arg1){
Arg1 = arg1 || 10; // 如果arg1没有被设置的话,Arg1将被默认设成10
}
23、使用 map() 方法来遍历一个数组里的项
var squares = [1,2,3,4].map(function (val) {
return val * val;
});
// squares will be equal to [1, 4, 9, 16]
24、保留小数位
var num =2.443242342;
num = num.toFixed(4); // num will be equal to 2.4432
25、浮点数问题
0.1 + 0.2 === 0.3 // is false
9007199254740992 + 1 // is equal to 9007199254740992
9007199254740992 + 2 // is equal to 9007199254740994
为什么是false?0.1+0.2等于0.30000000000000004。别忘了,所有的JavaScript数字在内部都是以64位二进制表示的浮点数,符合IEEE 754标准。更多的介绍,可以阅读this blog post.你可以使用 toFixed() 和 toPrecision() 方法解决这个问题。