博客逐步迁移至 极客兔兔的小站javascript
上一篇随笔介绍了如何正确判断对象类型、避免变量污染,特殊值(null、undefined、NaN)的使用,以及其余Javascript中经常使用关键字与方法的优化,这篇随笔将着重介绍Javascript语言中的条件与循环优化。
若有问题,请不吝指出,很是感谢;若是喜欢,右下角点个推荐吧~html
// 方法一,假设value的值平均分布 // 方法一的平均查询次数是 (n+1)/2,即复杂度是O(N) // 方法二采用了二分查找,平均查找次数为lg(n),复杂度是对数级别的 if(value === 0){ func0(); } else if (value === 1){ func1(); } else if (value === 2){ func2(); } else if (value === 3){ func3(); } else if (value === 4){ func4(); } else if (value === 5){ func5(); } else if (value === 6){ func6(); } else if (value === 7){ func7(); } // 方法二(分治策略),为方便排版,压缩、省略部分代码块 if (value < 4) { if(value < 2){ if(value === 0){ func0(); } else { func1(); } }else { if(value === 2){ func2(); } else { func3(); } } } else { // 省略同上的结构... }
如下状况适合用switchjava
(1) 判断值超过2个,并且值是离散的。 例如 case '男' (2) 表达式的值是固定的,不是动态变化的(3) 表达式的值值通常为整数、字符串等类型的数据node
/* 适用状况一:条件执行代码不多,如使用if或switch显得笨重 */ function func1(key){ if(key === 0){ return ans0; } if(key === 1){ return ans1; } // 省略 2,3,4,5... } // 替换为 function func1(key){ var ans = [ans0,ans1,ans2,ans3 ... ]; return ans[key]; }
/* 适用状况二:条件执行代码不少,如用if或switch可读性不好 * 同时,执行代码可能屡次复用,并且总体性较强 * 这种写法经常使用在javasript框架中,书写钩子函数(Hook) * 可读性很高,并且容易扩展,代码自己即文档 */ function func1(key){ if(key === "created"){ /* ... 省略10行代码 */ } else if(key === "init"){ /* ... 省略10行代码 */ } // 省略 "resume","start","pause","destroy",... } // 替换为 var hooks = { "created": function(){ /* ... 省略10行代码 */ }; "init": function(){ /* ... 省略10行代码 */ }; // ... 省略更多属性 } function func1(key){ hooks[key](); }
使用&&运算时,从左到右计算表达式,一旦为false就返回,例如:数组
A && B,若是A为false,表达式返回false,再也不计算B。
A为true,会继续计算B,再决定返回值,这称为短路表达式
所以,若是B为false的几率大于A,写为B && A能够减小计算次数缓存
使用||运算时,一样先计算||左侧的表达式,例如:框架
A || B,若是A为true,表达式返回true,再也不计算B。
所以,若是B为true的几率大于A,写为B || A能够减小计算次数函数
a = {} || [] // => a = {},a并无被赋值为true,而是 {}
/* || */ var value = a || []; // 等价于 value = a ? a : []; // 等价于 if(a){ value = a; } else { value = []; } /* && */ var value = a && b; // 等价于 value = a ? b : a;
/* 当a和b均返回false时,返回一个新建对象 */ return a || b || {}; /* jQuery中大量使用短路表达式赋值 * 代码过于简洁,代码可读性会下降,适当使用 */ diff = cur && a.nodeType === 1 && b.nodeType === 1 && (~b.sourceIndex || MAX_NEGATIVE) - (~a.sourceIndex || MAX_NEGATIVE);
var value = !!( a || b) // => value = true/false if(!!(a && b)) // => 显式转换,与if(a && b)结果一致
items = [1,2,3]; items.forEach(function(value,index,array) { // ... func(value); }) // 等价于 var len = items.length; for(var i = 0; i < len; ++i ){ // ... func(items[i]); }
len
,若是不使用变量len暂存,那么每次循环都须要访问数组的length
属性,比起直接访问一个数字,访问一个对象属性的花销会更大。// 暂存变量前,获取 p#item,须要3次DOM操做, $('p#item').func1(); $('p#item').func2(); $('p#item').func3(); // 等价于(这里不考虑jQuery的链式操做) // 只须要一次DOM操做(DOM操做很是耗时) var p_item = $('p#item'); p_item.fun1(); // ...
/* 不暂存变量 */ var obj = { nickname:{} }; obj['nickname'].firstname = 'Tom'; obj['nickname'].lastname = 'Smith'; obj['nickname'].fullname = 'Tom Smith'; // 压缩结果 var a = { nickname:{} }; a['nickname'].firstname = 'Tom'; a['nickname'].lastname = 'Smith'; a['nickname'].fullname = 'Tom Smith'; /* 暂存变量 */ var obj = { nickname:{} }; var nickname = obj['nickname']; nickname.firstname = 'Tom'; nickname.lastname = 'Smith'; nickname.fullname = 'Tom Smith'; // 压缩结果以下 var a = { nickname:{} }; var b = a['nickname']; b.firstname = 'Tom'; b.lastname = 'Smith'; b.fullname = 'Tom Smith';
分享创造价值,喜欢这个系列文章,不妨关注一下~性能