我已经认真读完了《Effective Javascript编写高质量Javascript代码的68个有效方法》,可能是小弟水平有限,感觉翻译的非常拗口。不过还是GET到了一些新知识点。
1. 总是在严格模式下检查你的代码
ES5引入“严格模式”的概念,用来控制运行一些Javascript的使用特性。比如在严格模式下,不允许重新定义 arguments对象。
2. 小心Javascript浮点数运算的精度陷进
0.1 + 0.2; // 0.30000000000000004
在Javascript中小数点计算应该转换为整数计算。
3. 正确区分NaN
<script type="text/javascript">
console.log(isNaN(1)) // false
console.log(isNaN(NaN)); // true
console.log(isNaN('ddd')); // true
</script>
使用 isNaN(arg)的前提是你已经知道了arg是一个数字。NaN是JS中唯一不等一自身的值,所以可以使用如下方法判断是否为NaN:
var isReallyNaN = function(arg) {
return arg !== arg
}
4. 小心对象隐式转换
对象通过隐士式的调用自身的 toString
方法转换为字符串
<script type="text/javascript">
console.log(Math.toString()); // [object Math]
console.log(JSON.toString()); // [object JSON]
console.log(Object.toString()); // function Object() { [native code] }
console.log(Object.valueOf()); // ƒ Object() { [native code] }
</script>
对象通过隐士式的调用自身的 valueOf
方法转换为数字
<script type="text/javascript">
console.log(Object.valueOf()); // ƒ Object() { [native code] }
</script>
哪个更优先?
对象在作为操作数时,解释器总是优先调用valueOf(Date类型的对象在二元“+”运算时例外),而其他情况,解释器总是认为我们想要的是字符串,所以会优先调用toString()
<script type="text/javascript">
console.log(Math + 3); // [object Math]3 => 触发 toString
console.log(3 + Math); // 3[object Math] => 触发 toString
console.log(Math - 3); // NaN => 触发 valueOf
console.log(3 - Math); // NaN => 触发 valueOf
console.log(Math.valueOf()); // Math {abs: ƒ, acos: ƒ, acosh: ƒ, asin: ƒ, asinh: ƒ, …}
</script>
<script type="text/javascript">
var obj = {
toString: function () {
return 'objtoString'
},
valueOf: function () {
return 111
}
}
console.log(5 + obj); //116
console.log(obj + 5); //116
</script>
<script type="text/javascript">
var obj = {
toString: function () {
return 'objtoString'
}
}
console.log(5 + obj); //5objtoString
console.log(obj + 5); //5objtoString
</script>
<script type="text/javascript">
var obj = {
toString: function () {
return 'objtoString'
},
valueOf: function () {
return 111
}
}
console.log('5' + obj); //5111
console.log(obj + '5'); //1115
</script>
5. 理解eval
函数的使用
直接调用:
var x = 'global'
function test () {
var x = 'local';
return eval("x");
}
console.log(test()); // local
间接调用:
var x = 'global'
function test () {
var x = 'local';
var f = eval;
return f("x");
}
console.log(test()); // global
间接调用的简写:
var x = 'global'
function test () {
var x = 'local';
return (0, eval)("x");
}
console.log(test()); // local
6. 异步循环的唯一方法:递归
?我刚写前端时用过for循环!!!
7. 尽量使用无状态的api
当api的调用涉及到程序的内部状态时,该api将会变得很复杂,应该继续拆分。