Javascript中的陷阱大集合【译】
然而,这样往往会误导我们,而且我们也不需要这样子来比较。在上面的例子中,我们完全可以先将字符串转换成数字型,然后利用对类型敏感的三重等号(===)来进行比较,如:
//true - 空字符串会被强制转换为数字0.0 == "0" //true - 数字0会被强制转换成字符串"0""" == "0" //false - 两操作数都是字符串所以不执行强制转换如果使用三重等号,上面的三个比较都将返回false。
parseInt不把10作为数字基数
如果你忽略parseInt的第二个参数,那么数字的基数将由下面的规则所决定:
默认基数为10,即按10进制解析 如果数字以0x开头,那么基数为16,即按16进制解析 如果数字以0开头,那么基数为8,即按8进制解析一个常见的错误是我们让用户输入以0开头的数字,这时候它就按8进制的方式去解析了,于是我们就看到了如下的效果:
如果要替换所有的匹配项,我们可以使用正则表达式,并为他它添加全局修饰符,如下代码:
全局修饰符确保了替换函数找到第一个匹配项后不会停止对下一个匹配项的替换。
“+"操作符会执行相加操作和字符串连接操作
php作为另一种弱类型语言,可以使用”.“操作符对字符串进行连接。Javascript却不是这样的 - 所以当操作数是字符串的时候”a+b“通常是执行连接操作。如果你想执行数字相加那你就要引起注意了,因为输入的内容可能是字符串类型的,所以你在执行相 加操作前需要先将其转换成数字类型,代码如下:
// 2尽管有时候你想用减法将字符串从另一个字符串中减掉,但这时候往往会产生一些逻辑错误。
很多时候我们用数字和空串相加来实现数字转换成字符串的操作,代码如下:
//truetypeof "" === "string" //truetypeof [] === "array"; //falseinstanceof String; //falsenew String("hello") instanceof String; //true
由于Array实际上不是内置类型(只是伪装成内置类型 - 因此对它使用typeof不能得到预期的结果),但是使用instanceof就能得到预期效果了,代码如下所示:
var b = new Boolean(true);var b = true;var c = new Array("one", "two");var c = ["one", "two"];var d = new String("hello");var d = "hello"var e = new Function("greeting", "alert(greeting);");var e = function(greeting) { alert(greeting); };然而,如果你使用new关键字来构造上面其中的一种类型,你实际上将会得到一个类型为Object并且继承自你要构造的类型的原型的对象(Function类型除外)。所以尽管你用new关键字构造了一个Number类型,它也将是一个Object类型,如下代码:
console.log(a); // "bob" - still in scope }()); }};obj.doSomething();//true
另外NaN和任何东西比较都是false:
NaN === NaN; // false
因为NaN之间是不能比较的,唯一判断一个数字是否为NaN的方法是调用isNaN方法。
从另一个方面可以说明,我们也可以用函数isFinite,当其中一个操作数为NaN或者InFinity时返回false。
arguments对象
在一个函数中,我们可以引用arguments对象来遍历传入的参数列表,第一个比较怪异的地方是这个对象并不是Array,而是一个类似 Array的对象(有一个length属性,其值在0-length-1之间)。为了将其转换成array,我们可以array的splice函数来创建 其对应的array数组:
(function(){console.log(arguments instanceof Array); // falsevar argsArray = Array.prototype.slice.call(arguments);console.log(argsArray instanceof Array); // true}());第二个比较怪异的地方是当一个函数的签名中有显式arguments参数时,它们是可以被重新分配的并且arguments对象也会被改变。这就表明了arguments对象指向了变量本身。你不能利用arguments对象来给出它们的初始值:
(function(a){ alert(arguments[0]); //1 a = 2; alert(arguments[0]); //2}(1));结束本文!
这样我就总结完了这些javascript陷阱。我肯定还会有更多这样的陷阱,期待大家更多的意见和点评。
PS - 我真的很喜欢Javascript。
参考资料
http://www.scottlogic.co.uk/blog/luke-page/ http://www.felixcrux.com/posts/douglas-crockford-talk-waterloo/ http://dev.opera.com/articles/view/efficient-javascript/?page=2 http://www.amazon.co.uk/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742 https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special/typeof http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/