1.推荐使用全等和不全等操作符
ECMAScript 提供两组操作符:相等和不相等(== 和 !=)——先转换再比较,全等和不全等(=== 和!==)——仅比较而不转换
除了在比较之前不转换操作数之外,全等和不全等操作符与相等和不相等操作符没有什么区别
如下所示:
var result1 = ("66" == 66); //true,因为转换后相等 var result2 = ("66" === 66); //false,因为不同的数据类型不相等
要记住:null == undefined 会返回 true,因为它们是类似的值;但 null === undefined 会返 回 false,因为它们是不同类型的值。
由于相等和不相等操作符存在类型转换问题,而为了保持代码中数据类型的完整性,推荐使用全等和不全等操作符。如果变量的类型是已经确定了的,那么使用==是根本没必要的;如果类型不确定,应该手动做一下转换:
var code = "5"; if(parseInt(code) === 0){ }
2.不建议修改变量所保存值的类型
变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据。换句话说, 每个变量仅仅是一个用于保存值的占位符而已;如下代码:
var message = "hi";
像这样初始化变量并不会把它标记为字符串类型; 初始化的过程就是给变量赋一个值那么简单。因此,可以在修改变量值的同时修改值的类型:
var message = "hi"; message = 100; // 有效,但不推荐
这样给人的感觉就过于随意了,且可读性太差,同时,js引擎在进行编译的时候也需要额外的耗时,不利于性能。推荐的方式是在初始化变量的时候给变量一个默认值:
var message = "hi", found = false, age = 29
3.避免延长作用域链
在两种情况下会发生作用域链的延长:
- try-catch 语句的 catch 块;
- with 语句
这两个语句都会在作用域链的前端添加一个变量对象。对 with 语句来说,会将指定的对象添加到 作用域链中。对 catch 语句来说,会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。
我们知道,标识符解析是沿着作用域链一级一级地搜索标识符的过程。搜索过程始终从作用域链的前端开始, 然后逐级地向后回溯,直至找到标识符为止,因此作用域链越长,查找越慢。
4.缓存变量
比如数组长度:
for (let j = 0; j < area.geo.length; j++) { }
应该写到一个变量里,避免每次循环都去查找这个对象且计算长度
let geoLength = area.geo.length for (let j = 0; j < geoLength; j++) { }
另外,缓存变量可以进行dom的优化:
let odiv=document.getElementById('content'); //接下来是一些操作dom的代码。。。
这样避免了多次去查找dom元素,可以提高代码效率。
5.关于if语句
大多数编程语言中为常用的一个语句就是 if 语句,这里提三点建议:
(1)始终使用代码块
业界普遍推崇的佳实践是始终使用代码块,即使要执行的只有一行代码。因为这样可以消 除人们的误解,否则可能让人分不清在不同条件下要执行哪些语句。
if (i > 25) alert("Greater than 25."); // 单行语句 else { alert("Less than or equal to 25."); // 代码块中的语句 }
(2)用三目运算符取代简单的 if-else
比如一个简单的函数:
lightBackground () { if(this.mode === 'dark'){ return normal }else { return light } }
用三目运算符来写就不会显得很臃肿,给人的感觉很清晰
lightBackground () { return this.mode === 'dark' ? 'normal' : 'light' }
原来的五行代码现在需要一行就OK了,代码的执行效率也比之前的要高。
(3)优化嵌套的条件语句
比如有大量的if-else语句:
if (index === 0) { fn0(); } else if (index === 1) { fn1(); } else if (index === 2) { fn2(); } else if (index === 3) { fn3(); }
可以用switch语句来优化代码。从根本上讲,switch 语句就是为了让开发人员免于编写像上面这样的代码。
switch(index){ case 0: fn0(); break; case 1: fn(1); break; case 2: fn2(); break; case 3: fn3(); break; default: fn() }
或者使用对象的方法替代:
let idxObj = { 0: fn0, 1: fn1, 2: fn2, 3: fn3, 4: fn } if(num in idxObj){ idxObj[num]() }