四、强制类型转换:
JS中强制类型转换非常常见,常常非常危险。这一章来具体介绍强制类型转换。
一)、值类型转换:
将值从一种类型转换为另一种类型通常有两种形式:
- 类型转换(type casting),显式;
- 强制类型转换(coercion),隐式;
- JS中的强制类型转换总是返回标量基本类型值(字符串、数字、布尔值)。
- 类型转换发生在静态类型语言的编译阶段,强制类型转换发生在动态类型语言的运行时(runtime)。
其实这两种分类的修辞并不特别准确。因为类型转换
var b = 1;
var a = String(b); // "1"
实际上更像是“强制的”类型转换,因此我们更应该用 显式、隐式来区别这两种方式。
二)、抽象值操作:
抽象操作和转换规则定义了标量基本类型值之间的转换基本规则。
1、ToString:
-
(null o "null")
-
(undefined o "undefined")
-
(true o "true")
-
数字的字符串化则遵循通用规则
-
数组,将所有单元字符串以后再用“,”来连接(([1, 2, 3] o "1, 2, 3"))
JSON.stringify(..)也可以将JSON对象序列化为字符串也用到了TOSTRING。
2、ToNumber:
- (true o 1, false o 0)
- (undefined o NaN)
- (null o 0)
3、ToBoolean:
假值会被强制转换为false,其他的值都会被判断为true。假值有:
- undefined
- null
- false
- +0、-0和NaN
- ""
- 假值对象
三)、显式强制类型转换:
显式强制类型转换可以将类型转换表达更加清楚,许多静态语言中的类型转换都是由此种方法实施。
四)、隐式强制类型转换:
隐式强制类型转换带来了隐患,同时也带来极大地遍历,可以说是动态语言的缺点也是优点。
// 静态类型的类型转换
SomeType x = SomeType(AnotherType(y))
// 动态语言的类型转换
SomeType x = SomeType(y)
五)、宽松相等和严格相等:
这里存在一个非常常见的 误区:==(宽松相等)”检查值是否相等,===检查值和类型是否相等。
而正确的解释是:==允许在相等比较中进行强制类型转换,而===不允许。
1、相等比较操作的性能:
前面对两个相等的不同解释同时表明性能的不同:
不同于误区,==的性能更差,因为并不是它比===少做一个检查类型,而是多做了一个强制类型转换。
2、抽象相等:
==操作符带来的强制类型转换,导致了抽象相等可能导致的危险。
六)、抽象关系比较:
<、>等关系操作符也会带来强制类型转换的风险。