JavaScript中隐式的强制转换

来源:互联网 发布:淘宝卖家查看退款记录 编辑:程序博客网 时间:2024/05/19 22:26

结果为null的变量在算术运算中不会导致失败,而是被隐式地转换为0;一个未定义的变量将被转换为特殊的浮点数值NaN不是立即抛出一个异常,而是继续运算,往往导致一些令人困惑和不可预测的结果。无奈的是,即便是测试NaN值也是异常困难的,这有两个原因。NaN不等于其本身。因此测试一个值是否等于NaN根本行不通。

var x = NaN;

x === NaN;//false

另外,标准的库函数isNaN也不是很可靠,因为它带有自己的隐式强制转换,在测试其参数之前,会将参数转换为数字。

isNaN(NaN);//true

但是对于其他绝对不是NaN,但会被强制转换为NaN的值,使用isNaN方法是无法区分的。

isNaN("foo");    //trueisNaN("undefined") //trueisNaN({});  //trueisNaN({valueOf:"foo"});//true

有一个既简单又可靠的习惯用法用于测试NaN,虽然稍微有点不直观。由于NaN是JavaScript中唯一一个不等于其自身的值,因此,你可以随时通过检查一个值是否等于其自身的方式来测试该值是否是NaN.

var a =NaN;a!==a;  //truevar b = "foo";b!==b;  //false

将这种模式抽象为一个清晰命名的适用工具函数。

function  isReallyNaN(x){return x!==x;}

对象也可以被强制转换为原始值。最常见的用法是转换为字符串。

”the Math object:" +Math;//"the Math object:[object Math]""the JSON object:" +JSON;//"the JSON object:[object JSON]"
对象通过隐式地调用其自身的toString方法转换为字符串。你可以调用对象的toString方法进行测试。

Math.toString();//"[object Math]"JSON.toString();//"[object JSON]"

对象也可以通过其valueOf方法转换为数字。通过定义类似下面这些方法,你可以控制对象的类型转换。

"J"+{toS"tring;function(){return "S";}};//"JS""2" *{valueOf:function(){return 3;}};   //6
当一个对象同时包含toString和valueOf方法时,运算符+应该调用哪个方法并不明显--做字符串链接还是加法应该根据参数的类型,但是存在隐式的强制转换,因此类型并不是显而易见!JavaScript通过盲目地选择valueOf方法而不是toString方法来解决这种含糊的情况。但是,这就意味着如果有人打算对一个对象执行字符串连接操作,那么产生的行为将会出乎意料。

var obj={toString:function(){return "[object MyObject]";},valueOf:function(){return 17;}};"object:"+obj;//"object:17"
这个例子的说明,valueOf方法才是真正是为那些代表数值的对象而设计的。对于这些对象,toString和valueOf方法应返回一致的结果,因此,不管是对象的连接还是对象的相加,重载的运算符+总是一致的行为。一般情况下,字符串的强制转换远比数字的强制转换更常见、更有用。最好避免使用valueOf方法,除非对象的确是一个数字的抽象,并且obj.toString()能产生一个obj.valueOf的字符串表示。

总结:

类型错误可能被隐式的强制转换所隐藏。

重载的运算符+是进行加法运算还是字符串连接操作取决于其参数类型。

对象通过valueOf方法强制转换为数字,通过toString方法强制转换为字符串。

具有valueOf方法的对象应该实现toString方法,返回一个valueOf方法产生的数字的字符串表示。

测试一个值是否为未定义的值,应该使用typeof或者undefined进行比较而不是使用真值运算。

阅读全文
0 0