js中的对象可以被转换成以下3个基本数据类型:
1、Nunber
2、String
3、Boolean
对上述转换的理解,我们可以绕过缺陷,并写出更整洁的代码。
一、字符转换
当需要一个对象的字符表示时候,将发生字符传唤。
e.g.在alert中输出obj
alert(obj) // [object Object]
当然,也可以显示转换,String(obj);
对象转换成字符串的逻辑如下:
1、如果对象有toString方法,则调用该方法,并返回相应的结果;
PS:代码通常会执行到这,因为在所有对象中都有toString方法。
2、如果对象有valueOf方法,则调用该方法,并返回相应的结果;
3、否则抛出异常。
通常,所有对象toString方法,内置对象都有自己toString
实现:
e.g.
alert( [1,2] ) // toString for Arrays lists elements "1,2"
alert( new Date ) // toString for Dates outputs the date as a string
e.g.
firstName: 'John',
toString: function() {
return 'User ' + this.firstName
}
}
alert( user ) // User John
在JavaScript中还有另一种转换,虽然没有toString用的广泛
,但在JS引擎内部,用得更频繁。
Math.sin(obj)
isNaN(obj)
包括算术运算符: +obj
;2、用于比较,e.g. obj == 'John'
PS:下面两种比较不会发生类型转换,
a)在严格比较(===)中,不会发生任何的类型转换,
b)在非严格比较中,如果参数都是对象,不会发生类型转换,通常,如果两个对象引用统一对象,则返回true.
Number(obj)
步骤 如下:
1、如果对象有valueOf方法,则调用该方法,并返回相应的结果;
2、否则如果对象有toString方法,则调用该方法,并返回相应的结果;
3、否则抛出异常。
alert( +new Date() ) // Microseconds till 1 Jan 1970
valueOf
, 这意味着数字转换基本上调用toString方法
。e.g.
num: 777,
valueOf: function() {
return this.num
}
}
alert( +room ) // 777
num: 777,
toString: function() {
return this.num
}
}
alert( room / 3 ) // 259
加法
+arr
会给NaN
: 全等/比较测试中的转换
当一个参数是基本类型的时候,对象将被强制转换,
e.g.
下面的比较将会被转化为基本类型
valueOf: function() { return 1 }
}
var b = {
valueOf: function() { return 0 }
}
alert( a > b ) // 1 > 0, true
[[toBoolean]]
。 如果发生在布尔上下文中,如if(obj)
while(obj)
等。
对象可能无法实现自己的这种转换,也没有其他特殊的方法。 相反,有一个硬编码的换算表:
PS:不像其他的编程语言,比如PHP,'0'在JS中返回的是true在下面的例子中发生数字转换
alert( "\n0\n" == 0 ) // true
alert( "\n0\n" == false ) // true
[0]
和"\n0\n"
是false,因为他们等于0
。if ("\n0\n") alert(2) // 2, if treats "\n0\n" as true
a == b
,但在布尔上下文中, a
是true
, b
是false
。计算下下面表达式,完成时,看下下面的解决办法:
"2" * "3"
4 + 5 + "px"
"$" + 4 + 5
"4" - 2
"4px" - 2
7 / 0
{}[0]
parseInt("09")
5 && 2
2 && 5
5 || 0
0 || 5
"2" * "3" = 6
4 + 5 + "px" = "9px"
"$" + 4 + 5 = "$45"
"4" - 2 = 2
"4px" - 2 = NaN
7 / 0 = Infinity
{}[0] = undefined
parseInt("09") = "0" or "9" // octal or decimal, depends on the browser
5 && 2 = 2
2 && 5 = 5
5 || 0 = 5
0 || 5 = 5
总结
在JavaScript中有三个转换,这取决于具体情况:
- 字符串输出,使用
toString
。 - 数字:数学函数,操作符,使用
valueOf
后使用toString
。 - 布尔值:根据下表转换。
这是不同于大多数其他编程语言,当你了解之后,其实很简单。
最准确的转换算法,参考规范:ECMA-262第五版,特别是11.8.5(关系比较),和11.9.3(相等比较)和9.1(toPrimitive)和9.3(toNumber)。
参考: