Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【JavaScript】数据类型转换 #40

Open
Tracked by #6
swiftwind0405 opened this issue Apr 14, 2020 · 0 comments
Open
Tracked by #6

【JavaScript】数据类型转换 #40

swiftwind0405 opened this issue Apr 14, 2020 · 0 comments

Comments

@swiftwind0405
Copy link
Owner

swiftwind0405 commented Apr 14, 2020

其它数据类型转布尔值

当我们在使用 Boolean() 来进行转换时,有如下转换规则:

参数类型 结果
false、undefined、null、+0、-0、NaN、"" false
除了上面的情况 true

另外需要注意的是,如果在使用Boolean()时不传参数结果也是为false

原始值转字符串

参数类型 结果
Undefined "undefined"
Null "null"
Boolean 如果参数是 true,返回 "true"。参数为 false,返回 "false"
Number 看下面题目
String 返回与之相等的值
Symbol "Symbol()"

数字转字符串

console.log(String(0)) // '0'
console.log(String(1)) // '1'
console.log(String(100)) // '100'
console.log(String(NaN)) // 'NaN'
console.log(String(10n)) // '10'
console.log(String(10n) === '10') // true

原始值转数字

参数类型 结果
Undefined NaN
Null +0
Boolean 如果参数是 true,返回 1。参数为 false,返回 +0
Number 返回与之相等的值
String 纯数字的字符串(包括小数和负数、各进制的数),会被转为相应的数字,否则为NaN
Symbol 使用Number()转会报错

记忆方法:

  • 纯数字的字符串(包括小数和负数、各进制的数),会被转为相应的数字
  • null 转为 0
  • Symbol 会报错
  • 其它的基本类型,包括非纯数字的字符串、NaNundefined 都会被转为 NaN

原始值转对象

console.log(new Object('1')) // String{'1'}
console.log(new Object(1)) // Number{1}
console.log(new Object(true)) // Boolean{true}
console.log(new Object(Symbol(1))) // Symbol{Symbol(1)}
console.log(new Object(10n)) // BigInt{10n}

console.log(new Object(null)) // {}
console.log(new Object(undefined)) // {}

传入的基本数据类型是什么类型的,那么最终的结果就会转为对应的包装类,但是对于 nullundefined 它们会被忽略,生成的会是一个空对象。

原始值转对象主要有以下总结:

  • StringNumberBoolean 有两种用法,配合 new 使用和不配合 new 使用,但是 ES6 规范不建议使用 new 来创建基本类型的包装类。
  • 现在更加推荐用 new Object() 来创建或转换为一个基本类型的包装类。

基本类型的包装对象的特点:

  • 使用 typeof 检测它,结果是 object,说明它是一个对象
  • 使用 toString() 调用的时候返回的是原始值的字符串

toPrimitive

ToPrimitive(input, PreferredType?)

参数:

  • 参数一:input,表示要处理的输入值
  • 参数二:PerferredType,期望转换的类型,可以看到语法后面有个问号,表示是非必填的。它只有两个可选值,NumberString

而它对于传入参数的处理是比较复杂的,看看这幅流程图:
image

数组转字符串主要是这样:

  • 空数组 [] 是被转换为空字符串 ""
  • 若是数组不为空的话,则将每一项转换为字符串然后再用","连接

配合着引用类型转字符串的图:
image

使用==比较时的类型转换

NaN 与其它类型的比较

NaN这个六亲不认的连它自己都不全等(也就是 NaN===NaN 的结果为false),只有用 Object.is(NaN, NaN) 才会被判断为true。

null/undefined 与其它类型的比较

若是一方为null、undefined,则另一方必须为null或者undefined才为true,也就是null == undefined为true或者null == null为true,因为undefined派生于null。

String 与 Number 的比较

会把String转成Number再来比较:

image

Boolean 与其它类型的比较

会将Boolean转为Number来比较,而通过上篇我们知道,Boolean转Number那是相当简单的,只有两种情况:

  • true => 1
  • false => 0

image

Object 与 String/Number/Symbol 的比较

会将对象执行类似ToNumber操作之后再进行比较的,但是又由于对象的valueOf()基本都是它本身,所以我们可以认为省略了这一步:

image

总结

当使用 == 进行比较的时候,会有以下转换规则(判断规则):

  1. 两边类型如果相同,值相等则相等,如 2 == 3 肯定是为 false
  2. 比较的双方都为基本数据类型:
    • 若是一方为 nullundefined,则另一方必须为 null 或者 undefined 才为 true,也就是 null == undefinedtrue 或者 null == nulltrue,因为 undefined 派生于 null
    • 其中一方为 String,是的话则把 String 转为 Number 再来比较
    • 其中一方为 Boolean,是的话则将 Boolean 转为 Number再来比较
  3. 比较的一方有引用类型:
    • 将引用类型遵循类似ToNumber的转换形式来进行比较(也就是toPrimitive(obj, 'defalut')
    • 两方都为引用类型,则判断它们是不是指向同一个对象

当一方有为对象的时候,实际是会将对象执行ToNumber操作之后再进行比较的,但是又由于对象的valueOf()基本都是它本身,所以我们可以认为省略了这一步。

可以对照下面的流程图看一下:

image

! 运算符的转换

当使用 ! 的时候,实际上会将 ! 后面的值转换为布尔类型来进行比较,而且这种转换是不会经过 valueOf 或者 toString 的,而是直接转换为了布尔值。

+-*/% 的类型转换

  1. -*/% 这四种都会把符号两边转成数字来进行运算
  2. + 由于不仅是数字运算符,还是字符串的连接符,所以分为两种情况:
    • 两端都是数字则进行数字计算
    • 有一端是字符串,就会把另一端也转换为字符串进行连接

对象的 + 号类型转换:

  • 对象在进行 + 号字符串连接的时候,toPrimitive 的参数 hintdefault,但是default 的执行顺序和number一样都是先判断有没有 valueOf,有的话执行 valueOf,然后判断 valueof 后的返回值,若是是引用类型则继续执行 toString
  • 日期在进行 + 号字符串连接的时候,优先调用 toString() 方法。
  • 一元正号是转换其他对象到数值的最快方法,也是最推荐的做法,因为它不会对数值执行任何多余操作

参考资料

@swiftwind0405 swiftwind0405 changed the title 数据类型转换 【JavaScript】数据类型转换 Apr 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant