差不多两年前写了个选择器whiz,除在DOM查找方面做了许多优化工作之外,还在代码优化上做了很多工作,一直没有分享。抽空总结一下,基本上在jQuery、Mootools和YUI的源码里面都可以看到这些写法。有些是已经在网上分享很多遍了,众所周知的,也有一些可能写了多年的JavaScript的开发人员也不一定想得到的。如果有说得不正确的地方,还请大家指出。还有特别说明的是,其中某些写法不是很推荐,虽然代码简洁了,但是有可能造成阅读困难。
js是解释性语言,相比编译性语言执行速度要慢。如果浏览器已经实现了该方法,就不要再用js再去实现一遍了。另外,绝大部分情况下,浏览器已经实现的方法已经在算法方面做了很多优化,再重复实现一遍只是浪费时间和精力还有带宽。当然,如果你只是为了练习算法,那另当别论。
代码的瓶颈大多在循环,少一层循环,就能数倍地提高性能。如果要对一个数组的每个元素进行多次操作,尽可能使用一次循环,多次操作,而不是多次循环,每次循环执行一次操作。尤其是在进行多个正则匹配的时候,尽可能合并正则表达式,在一次遍历中尽可能找到相应的匹配。
通常循环的写法:
var objs = [obj1, obj2, obj3], i = 0; len = objs.length; for(i = 0; i < len; i++){ dosth(obj); }
当循环遍历的对象是object时,可以采用下面的方式来写:
var objs = [obj1, obj2, obj3], obj, i = 0; while(obj = objs[i++]){ dosth(obj); }
特别注意,如果你的数组里面有可能出现0, false, null等等在条件判断为false的值,这种写法是不正确的。
通常的switch写法:
function fun_a(){} function fun_b(){} function fun_c(){} switch(con){ case 'a': fun_a(); break; case 'b': fun_b(); break; case 'c': fun_c(); break; }
另外一种写法:
function fun_a(){} function fun_b(){} function fun_c(){} var funs = { 'a': fun_a, 'b': fun_b, 'c': fun_c }; funs[con]();
取值或者函数调用都可以用类似的方式来做。
通常情况下:
if(a){ dosth(); }
可以这样写:
a && dosth();
很多时候,我们要连续创建一些简单的object对象,并且拥有默认的属性,很多人会这么写:
function Klass(){ this.prop_a = ''; this.prop_b = []; this.prop_c = 0; } var objs = [], i = 0, obj; while(i<100){ obj = new Klass(); obj.prop_c = i; objs.push(obj); }
换种写法看看:
function create(){ return { prop_a : '', prop_b : [], prop_c : 0 }; } var objs = [], i = 0, obj; while(i<100){ obj = create(); obj.prop_c = i; objs.push(obj); }
当然还有直接声明的方式,但是复用性会差一些。
直接用true和false做标记,不要使用数字或者字符串的1和0来做标记,直接也高效。
其他的优化方法已经有很多分享了,大家可以Google一下,另外《javascript高级程序设计》一书中也对JavaScript性能优化做了较为详细的阐述。