JavaScript的强制类型转换(一)

180 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情

大家好!我是前端爬楼工程师🚹,一个野生程序员。好奇新技术,仰慕牛大佬。如果喜欢我的文章,可以关注➕点赞,为我注入能量,与我一同成长吧~


类型转换式在静态类型语言编译的情况下进行,如TypeScript,强制类型转换发生在运行时。

JavaScript属于后者,强制类型转换后总是返回标量的基本类型,如:string, number , boolean,而不会返回对象或者函数。

这种使用构造函数转换属于显式的转换:

new String(2)

这种使用拼接空字符串属于隐式的转换:

'' + 2

js内部的类型转换方式

转换成字符串、数字或布尔的方式分别是ToString,ToNumber,ToBoolean。这些都是内部使用的操作,也就是引擎使用的。

ToString

ToString,首先会判断是否有自行定义的toString()方法,否则会走Object.prototype.totString(),返回内部属性[[Class]]

// 例子:
null -> "null"
true -> "true"
undefined -> "undefined"
[1,2,3].toString() -> "1,2,3"

JSON的字符串化

对应的工具函数JSON.stringify(),如果有自行定义的toJSON()方法,对JSON对象序列化为字符串也用到了ToStringJSON的字符串换不叫强制类型转换。

安全的JSON值都可以用JSON.stringify()字符串化。不安全的undefined,function,symbol和循环引用的对象则会被忽略。

var a = {b:1, c:a}
JSON.stringify(a) // '{"b":1}'

数组里遇到了不安全的值会返回null

JSON.stringify(undefined) // "undefined"
JSON.stringify([function(){}, undefined, Symbol('x')]) // '[null,null,null]'

JSON.stringify()的第二个参数是replacer

  • 如果replacer是一个数组,指的是需要序列化的属性名称;
JSON.stringify({a:1, b:2, c:3}, ['b','c']) // '{"b":2,"c":3}'
  • 如果replacer是一个函数,取得是函数的返回值,函数传递的两个参数是键和值
JSON.stringify({a:1, b:2, c:3}, (k , v)=> {
    if(k !== 'a') return v;
})
// '{"b":2,"c":3}'

JSON.stringify([1,2,3], (k , v)=> {
    if(k != '0') return v; // 数组里k对应的是索引
})
//'[null,2,3]'

JSON.stringify()的第三个参数是space: 用来指定每一级缩进的字符数

JSON.stringify([1,2,3], (k , v)=> {
    if(k != '0') return v;
} , '     ')
//  '[\n     null,\n     2,\n     3\n]'
JSON.stringify([1,2,3],null, '---')
// '[\n---1,\n---2,\n---3\n]'

ToNumber

true -> 1
false -> 0
undefined -> NaN // 数字处理失败也会转换成NaN
null -> 0

对象转换为数字,通过两个步骤,首先转换基本类型(运用ToPrimitive操作),然后强转为数字类型。

对象转换基本类型首先通过DefaultValue检查是否有valueOf(),如果有并且返回基本类型值,就使用该值进行强制类型转换,如果没用就使用toString()的返回值进行强制类型转换。如果valueOf(),toString()均不返回基本类型,则产生TypeError的错误。

var a = {
 valueOf(){
     return '1'
 }
}
var b = {
 valueOf(){
     return [1,2]
 }
 toString(){
     return '1'
 }
}
Number(a) // 1
Number(b) // 1

ToBoolean :有两个值: true | false

 // 会触发ToBoolean操作
 ! 
 if(..){}
 do..while(..) / while(..)
 for(..;..;..) 
  • undefined
  • null
  • false
  • +0,-0,NaN
  • ""

以上通过布尔类型强制转换结果都是false