本篇对这本书的附录进行摘要。
附录A:糟粕
A.1全局变量
全局变量是javascript所有糟糕特性中最糟糕的。
全局变量是在所有作用域中均可见的变量。如果某些全局变量碰巧和子程序中的变量名称相同,那么他们将互相冲突可能导致程序无法运行,通常还难以调试。
定义全局变量有3中方式:
(1)脱离任何函数安排一个var语句:
var foo=value;
(2)直接添加一个属性到全局对象上,如果是web浏览器,全局对象名是window:
window.foo=value;
(3)直接使用未经声明的变量,叫做隐式全局变量:
foo=value;
这种隐式声明全局变量的方式,让初学者很容易出错。
A.2作用域
javascript没有块级作用域,只有函数作用域。所以声明一个变量做好的方式是在函数顶部。
A.3自动插入分号
比如一个return语句返回一个值,这个值表达式的开始部分必须和return在同一行上,否则会返回undefined。
return
{
foo:1
};
正确的方式为:
return{
foo:1
};
A.4保留字
保留字不能被用来命名变量或参数。当被用作对象字面量的键值时,必须用引号括起来。
var o={case:true}; //非法
var o={'case':true}; //正确
o['case']; //正确
o[case]; //错误
A.5 Unicode
javascript字符是16位的。Unicode把一对字符视为单一的字符,而javascript认为一对字符是2个不同的字符。
A.6 typeof
typeof无法检测出null值:
typeof null=='object';
typeof对正则表达式的实现也不一致,有的实现是'object',有的是'function'。
A.7 parseInt
parseInt在遇到非数字时停止解析,如:
parseInt('12'); //12
parseInt('12 top'); //12
可以看到输出结果是一样的。
如果字符串第一位是0,则parseInt会按八进制而不是十进制来解析。所以parseInt('08')会返回0。这样会在解析日志或时间时出现问题。解决方法是:在parseInt中再加一个参数:
parseInt("08",10); //8
A.8 +
+运算符可以做加法运算和字符串连接,这取决于参数的类型。
在做加法的时候,请确保所有参数是整数。
A.9 浮点数
二进制的浮点数不能正确的处理十进制的小数,因此0.1+0.2不等于0.3。幸运的是,浮点数的整数运算是精确的,所以小数表现出来的问题可以通过指定精度避免。
A.10 NaN
NaN表示不是一个数字,但下面的表达式是正确的:
typeof NaN === 'number'; //true
NaN不等于他自己。
NaN === NaN; //false
判断一个值是否可用作一个数字的最佳方法是使用isFinite函数,他会筛除掉NaN和Infinity。可以这样定义一个isNumber函数:
function isNumber(value){
return typeof value === 'number' && isFinite(value);
}
A.11 伪数组
javascript没有真正的数组,数组不会产生越界错误。
A.12 假值
undefined和NaN并不是常量,而是全局变量,并且你可以改变他们的值。千万不要这样做。
A.13 hasOwnProperty(略)
A.14对象
javascript的对象永远不会用真正的空对象,因为他们可以从原型链中取得成员元素。
附录B:鸡肋
B.1 ==
==和!=会在两个运算数数据类型相同是才会比较,否则会先强制转换。
''=='0'; //false
0==''; //true
0=='0'; //true
false=='false'; //false
false=='0'; //true
false==undefined; //false
false==null; //false
null==undefined; //true
' \t\r\n '==0; //true
可以看到,使用==非常混乱,所以尽量使用===和!==比较。
B.2 with--不要使用它!
B.3 eval--不要使用它!(降低安全性,难以阅读,效率低)
B.4 continue--效率低,尽量不要使用!
B.5 switch贯穿--难以察觉错误,尽量不要使用!
B.6 缺少块的语句
if(ok)
t=true;
advance();
实际上表达的是:
if(true){
t=true;
}
advance();
B.7 ++ --
尽量不要使用。
B.8 位运算符--效率非常低,不要使用!
B.9 function语句对比函数表达式(略)
B.10 类型的包装对象
不要使用new Boolean(), new Number(), new String()。
避免使用new Object(), new Array()。可使用{}和[]来代替。
B.11 new
new操作符用来创建一个新对象,并把新创建的对象绑定给了构造器的this对象。一旦你忘记了使用new,你得到的是一个普通函数的调用,这是this就会绑定在了全局对象上,这会带来很大的问题。而且编译器也不会报错或警告。
所以规定构造函数名首字母要大写,还有一个更好的方法就是不去使用new。
B.12 void--这是一个运算符,返回undefined,避免使用它!
来源:oschina
链接:https://my.oschina.net/u/257704/blog/387536