有意思的 JavaScript
原始值到原始值的转换
原始值转化为布尔值
所有的假值(undefined、null、0、-0、NaN、'')会被转化为 false,其他都会本转化为 true。原始值转化为字符串
都相当于原始值 + ""-
原始值转为数字
+ '66' // 66 + ' 6 7 ' // NaN
- 布尔值转数字:true -> 1,false -> 0
- 字符串转数字:以数字表示的字符串可以直接转为字符串,如果字符串头尾有空格会忽略,但是空格在中间,转换结果就是 NaN。
原始值到对象的转换
- null 和 undefined 转对象直接抛异常。
- 原始值通过调用 String()、Number()、Bollean() 构造函数,转换为他们各自的包装对象。
对象到原始值的转换
- 对象转为布尔都为 true。
- 对象到字符串
- 如果对象有 toString() 方法,就调用 toString() 方法。如果该方法返回原始值,就将这个值转化为字符串。
- 如过对象没有 toString() 方法或者该方法返回的不是原始值,就会调用该对象的 valueOf() 方法。如果存在就调用这个方法,如果返回值是原始值,就转化为字符串。
- 否则就报错。
- 对象到数字
- 对象转化为数字做了跟对象转化为字符串做了相同的事情,不同的是后者先调用 valueOf() 方法,如果调用失败或者返回不是原始值,就调用 toString() 方法。
- 补充。一些常用内置对象 toString 方法 和 valueOf 的转换规则
-
toString 相关
-
valueOf() 相关
-
toString 相关
== 运算符如何进行类型转换
- 如果一个值是 null,另一个值是 undefined,则相等
- 如果一个是字符串,另一个值是数字,则把字符串转换成数字,进行比较
- 如果一个是对象,则把 true 转换成 1 再进行比较;如果任意值是 false,则把 false 转换成 0 再进行比较
- 如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较。对象转换成基础类型,利用他的 toString 或者 valueOf 方法。 js 核心内置类,会尝试 valueOf 先于 toString (可以理解为对象优先转换成数字),例外的是 Date, Date 利用的是 toString 转换。非 js 核心的对象,通过自己的实现中定义的方法转换成原始值。
+ 运算符如何进行类型转化
- 如果作为一元运算符就是转化为数字,常常用来将字符串转化为数字
+ '2' // 2 2 + false // 2
- 如果作为二元运算符就有两种转换方式
- 两边如果有字符串,另一边会转化为字符串进行相加。
- 如果没有字符串,两边都会转化为数字进行相加,对象也根据前面的方法转化为原始值数字。
- 如果其中的一个操作数是对象,则将对象转换成原始值,日期对象会通过 toString() 方法进行转换,其他对象通过 valueOf() 方法进行转换,但是大多数方法都是不具备可用的 valueOf() 方法,所以还是会通过 toString() 方法执行转换。
解析
(! + [] + [] + ! []).length // 9
运算顺序:
-
![]
: [] 转化布尔值的时候会转化为true
,所以转化为false
。+[]
:加号作为一元操作符会被转化为数字 0,所以结果为:
(! 0 + [] + false).length
-
!0
为true
,[]
在二元操作符中会被转化为''
,
(true + '' + false).length
- 结果
('truefalse').length