从ES5标准看JavaScript的类型转换

原创 1275917839 随笔 JS 106阅读 2018-04-12 13:54:31 举报

更多文章欢迎光临我的个人博客

  • ToBoolean
  • ToNumber
  • ToString
  • ToPrimitive
  • 常见的类型转换
    • 相等操作符==
    • 运算符+

相对于JAVA和C这样的强语言,JS中的类型转换常常让学习这门语言的人觉得难以理解,甚至觉得这样的特性过于疯狂,例如下面的表达式:

这些表达式是如此的的难以理解,以至于你迫不及待要阅读这篇文章了( ̄▽ ̄)/ ,呃...Emm,或者你早已对此有所了解(~ ̄▽ ̄)~ ,复习一遍也无妨。

JS中的值类型有七种:

  • null
  • undefined
  • boolean
  • number
  • string
  • object
  • symbol

我们着重讨论的是前六种的类型转换,symbol不用做算术逻辑运算,也就不做讨论。

1.ToBoolean

先上标准:

https://i.loli.net/2018/03/24/5ab6151fc686c.png

我们将JS中可以转换为true和false的值称为truthy和falsy,对于truthy,它所包含的值是无限的,所以我们只列出为falsy的值

  • null
  • undefined
  • false
  • +0 -0 NaN
  • ''

除了以上的值,其余值在JS中都为true

2.ToNumber

https://i.loli.net/2018/03/24/5ab618152ee43.png

对于对象的类型转换会在ToPrimitive中单独讨论,我们先来看看string->number的转换,标准中的转换文法过于繁琐,大致将一个可以转换为数字的字符串分为三个部分,前,后以及真正有效的数字部分,我从中总结了一些比较常见的情况:

  • 字符串中数字部分的前后允许存在空白和行终止符
  • 字符串中的数字部分允许是其他进制数
  • 字符串中的数字部分允许指数形式
  • 字符串中数字部分允许存在任意位数的0前缀(仅限十进制)
  • 字符串中数字部分允许存在+,-前缀(仅限十进制)
  • 空字符串或者只含空白和行终止符的字符串会被转换为+0

3.ToString

https://i.loli.net/2018/03/24/5ab64e45b9b0c.png

对于null,undefined,boolean这三种值JS有它内建的字符串化表示

对于number->string的转换,标准也显得过于复杂,以下依然是总结:

  • NaN会被转换为'NaN'
  • 正值会丢弃+符号,负值会带上-
  • 除十进制之外的默认会被转换为十进制的表示形式(可以在toString中指定转换的进制)
  • 小数后面的0将会被舍弃(可以使用toFixed和toPrecision)
  • 指数会被展开

4.ToPrimitive

https://i.loli.net/2018/03/25/5ab71bef7abaf.png

本篇的重头戏来了,标准中说会调用对象的[[defaultValue]]内部方法返回一个基本类型,并且所有对象的这个方法是一致的,该方法实现如下图:

https://i.loli.net/2018/03/25/5ab71c13d8230.png

[[GET]]是对象的内部方法,可以传入一个属性名,得到该对象的对应属性值

isCallable抽象操作确定传入参数是否是一个可调用对象

[[Call]]是可调用对象的内部方法(例如函数对象),用于调用自身

结合图片和注释,ToPrimitive的算法就是根据暗示类型的不同来决定valueOf和toString方法的执行先后顺序,那么,暗示类型是如何确定的呢?

根据推测和日常的经验,我觉得大概就是String(123)的暗示类型是String,Number('123')的暗示类型是Number,诸如此类

5.常见的类型转换

1.相等操作符==

根据ES5标准,==使用抽象比较算法进行比较,具体内容如下:

https://i.loli.net/2018/03/24/5ab64161e6122.png

type函数用于得到传入参数的值类型

该算法分为十种情况,过于复杂,我们可以把它总结为四种情况:

1.type(x)与type(y)相同,情况如选项一所示

2.null==undefined

3.Boolean>Object>String>Number

上面这个式子意思是,当这四种类型两两使用==比较时,总是上述式子中优先级高的的先做类型转换,并且只有Object做ToPrimitive转换,其余做ToNumber转换

4.返回false

这样开头表达式的结果就可以解释了:

2.运算符+

这是我们最常用的拼接字符串方法,简单快捷,我们来看一下它的ES5标准:

https://i.loli.net/2018/03/24/5ab647cecd68c.png

算法很简单,先得到左右操作数的基本值,然后只要有一个操作数为string,则将两个操作数的toString()值相加,简单粗暴有效,但是在实际操作中需要注意一些特殊的情况,比如实现了自己valueOf方法的对象之类,得不到预期的结果

结合ToPrimitive和+运算符的ES5标准,我们可以解释开头另外一个表达式了:

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复