在这篇文章中,我将分享一些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()
方法解决这个问题。
|