JavaScript 是一个绝冠全球的编程语言, 可用于 web 开发, 移动应用开发 (PhoneGap,Appcelerator), 服务器端开发(Node.JS 和 Wakanda) 等等. JavaScript 还是很多新手踏入编程世界的第一个语言. 既可以用来显示浏览器中的简单提示框, 也可以通过 nodebot 或 nodruino 来控制机器人. 能够编写结构清晰, 性能高效的 JavaScript 代码的开发人员, 现如今已成了招聘市场最受追捧的人.
在这篇文章里, 将和大家分享一些 JavaScript 的技巧, 秘诀和最佳实践, 除了少数几个外, 不管是浏览器的 JavaScript 引擎, 还是服务器端 JavaScript 解释器, 均适用.
本文中的示例代码, 通过了在 GoogleChrome 30 最新版 (V83.20.17.15) 上的测试.
1, 首次为变量赋值时务必使用 var 关键字
变量没有声明而直接赋值得话, 默认会作为一个新的全局变量, 要尽量避免使用全局变量.
2, 使用 === 取代 ==
== 和!= 操作符会在需要的情况下自动转换数据类型. 但 === 和!== 不会, 它们会同时比较值和数据类型, 这也使得它们要比 == 和!= 快.
3,underfined,null,0,false,NaN, 空字符串的逻辑结果均为 false
4, 行尾使用分号
实践中最好还是使用分号, 忘了写也没事, 大部分情况下 JavaScript 解释器都会自动添加. 对于为何要使用分号, 可参考文章 JavaScript 中关于分号的真相.
5, 使用对象构造器
6, 小心使用 typeof,instanceof 和 contructor
typeof:JavaScript 一元操作符, 用于以字符串的形式返回变量的原始类型, 注意, typeofnull 也会返回 object, 大多数的对象类型 (数组 Array, 时间 Date 等) 也会返回 object
contructor: 内部原型属性, 可以通过代码重写
instanceof:JavaScript 操作符, 会在原型链中的构造器中搜索, 找到则返回 true, 否则返回 false
7, 使用自调用函数
函数在创建之后直接自动执行, 通常称之为自调用匿名函数 (Self-InvokedAnonymous Function) 或直接调用函数表达式(ImmediatelyInvoked Function Expression ). 格式如下:
8, 从数组中随机获取成员
9, 获取指定范围内的随机数
这个功能在生成测试用的假数据时特别有数, 比如介与指定范围内的工资数.
10, 生成从 0 到指定值的数字数组
varnumbersArray =[],max =100;for(vari=1;numbersArray.push(i++)<max;); //numbers = [1,2,3 ... 100]
11, 生成随机的字母数字字符串
12, 打乱数字数组的顺序
这里使用了 JavaScript 内置的数组排序函数, 更好的办法是用专门的代码来实现(如 Fisher-Yates 算法), 可以参见 Stack Overflow 上的这个讨论.
13, 字符串去空格
Java,C# 和 PHP 等语言都实现了专门的字符串去空格函数, 但 JavaScript 中是没有的, 可以通过下面的代码来为 String 对象函数一个 trim 函数:
新的 JavaScript 引擎已经有了 trim()的原生实现.
14, 数组之间追加
vararray1 =[12,"foo",{name"Joe"},-2458];vararray2 =["Doe",555,100];Array.prototype.push.apply(array1,array2);/*array1 值为 [12, "foo" , {name "Joe"} , -2458 , "Doe", 555 , 100] */
15, 对象转换为数组
16, 验证是否是数字
17, 验证是否是数组
但如果 toString()方法被重写过得话, 就行不通了. 也可以使用下面的方法:
如果在浏览器中没有使用 frame, 还可以用 instanceof, 但如果上下文太复杂, 也有可能出错.
18, 获取数组中的最大值和最小值
19, 清空数组
20, 不要直接从数组中 delete 或 remove 元素
如果对数组元素直接使用 delete, 其实并没有删除, 只是将元素置为了 undefined. 数组元素删除应使用 splice.
切忌:
而应:
删除对象的属性时可以使用 delete.
21, 使用 length 属性截断数组
前面的例子中用 length 属性清空数组, 同样还可用它来截断数组:
与此同时, 如果把 length 属性变大, 数组的长度值变会增加, 会使用 undefined 来作为新的元素填充. length 是一个可写的属性.
22, 在条件中使用逻辑与或
逻辑或还可用来设置默认值, 比如函数参数的默认值.
23, 使得 map()函数方法对数据循环
24, 留指定小数位数
注意, toFixec()返回的是字符串, 不是数字.
25, 浮点计算的问题
为什么呢? 因为 0.1+0.2 等于 0.30000000000000004.JavaScript 的数字都遵循 IEEE754 标准构建, 在内部都是 64 位浮点小数表示, 具体可以参见 JavaScript 中的数字是如何编码的.
可以通过使用 toFixed()和 toPrecision()来解决这个问题.
26, 通过 for-in 循环检查对象的属性
下面这样的用法, 可以防止迭代的时候进入到对象的原型属性中.
27, 逗号操作符
28, 临时存储用于计算和查询的变量
在 jQuery 选择器中, 可以临时存储整个 DOM 元素.
29, 提前检查传入 isFinite()的参数
30, 避免在数组中使用负数做索引
注意传给 splice 的索引参数不要是负数, 当是负数时, 会从数组结尾处删除元素.
31, 用 JSON 来序列化与反序列化
32, 不要使用 eval()或者函数构造器
eval()和函数构造器 (Functionconsturctor) 的开销较大, 每次调用, JavaScript 引擎都要将源代码转换为可执行的代码.
33, 避免使用 with()
使用 with()可以把变量加入到全局作用域中, 因此, 如果有其它的同名变量, 一来容易混淆, 二来值也会被覆盖.
34, 不要对数组使用 for-in
避免:
而是:
另外一个好处是, i 和 len 两个变量是在 for 循环的第一个声明中, 二者只会初始化一次, 这要比下面这种写法快:
如果传给 setTimeout()和 setInterval()一个字符串, 他们将会用类似于 eval 方式进行转换, 这肯定会要慢些, 因此不要使用:
而是用:
35, 使用 switch/case 代替一大叠的 if/else
当判断有超过两个分支的时候使用 switch/case 要更快一些, 而且也更优雅, 更利于代码的组织, 当然, 如果有超过 10 个分支, 就不要使用 switch/case 了.
36, 在 switch/case 中使用数字区间
其实, switch/case 中的 case 条件, 还可以这样写:
37, 使用对象作为对象的原型
下面这样, 便可以给定对象作为参数, 来创建以此为原型的新对象:
38,html 字段转换函数
39, 不要在循环内部使用 try-catch-finally
try-catch-finally 中 catch 部分在执行时会将异常赋给一个变量, 这个变量会被构建成一个运行时作用域内的新的变量.
切忌:
而应该:
40, 使用 XMLHttpRequests 时注意设置超时
XMLHttpRequests 在执行时, 当长时间没有响应 (如出现网络问题等) 时, 应该中止掉连接, 可以通过 setTimeout()来完成这个工作:
同时需要注意的是, 不要同时发起多个 XMLHttpRequests 请求.
41, 处理 WebSocket 的超时
通常情况下, WebSocket 连接创建后, 如果 30 秒内没有任何活动, 服务器端会对连接进行超时处理, 防火墙也可以对单位周期没有活动的连接进行超时处理. 为了防止这种情况的发生, 可以每隔一定时间, 往服务器发送一条空的消息. 可以通过下面这两个函数来实现这个需求, 一个用于使连接保持活动状态, 另一个专门用于结束这个状态.
keepAlive()函数可以放在 WebSocket 连接的 onOpen()方法的最后面, cancelKeepAlive()放在 onClose()方法的最末尾.
42, 时间注意原始操作符比函数调用快, 使用 VanillaJS
比如, 一般不要这样:
可以这样来代替:
43, 开发时注意代码结构, 上线前检查并压缩 JavaScript 代码
别忘了在写代码时使用一个代码美化工具. 使用 JSLint(一个语法检查工具)并且在上线前压缩代码(比如使用 JSMin). 注: 现在代码压缩一般推荐 UglifyJS
来源: http://developer.51cto.com/art/201812/588290.htm