js中让人头疼的数据转换

289 阅读4分钟

前言

你是否也有同款疑问:js中‘2’-1,‘1’+1的结果分别是什么,你看完就能知道结果,并且知道原因。

一 . 原始类型间的相互转化

1.原始值转boolean

原始转boolean.png 上述代码涵盖了原始值转boolean中各类情况,需要特别注意的是结果为的false情况:首先Boolean()默认值是false;除此之外传入0,false,undefined,null转化为boolean结果都是false,其他的均为true。

2.原始值转数字

原始值转数字.png 上述结果中需要特别记忆的是字符串‘0’,undefined,和null;非‘0’数字字符串的结果是0,其他数字字符串是该数字,而其他字符串是NaN。

值得注意的是,Number()内部原理是调用了toNumber(value)方法,只不过这个方法我们不能用。这里仅做了解,在后面理解原理中需要用到。

3.原始值转字符串

原始值转字符串.png 结果显而易见。所有类型转换为字符串都使传入的值直接变成了字符串。

与Number()类似,Stirng()内部调用的是toString()方法,这个方法我们常常用到。

二.原始类型与引用类型的相互转化

1.原始值转对象

通过String() Number() Boolean()这三个构造函数就可以轻松地将原始值转化为对象,接下来我们以String为例:

原始值转对象.png

大家有没有发现一个问题,通过上面三个构造函数new出来的对象并不能添加属性和方法,而我们自己定义的构造函数new出来的对象就可以添加属性和方法。根本原因就是通过这几个构造函数new出来的对象有个[[PrimitiveValue]]属性,这个属性就让这些对象被判定为原始类型,也就不能添加属性和方法。但是只有这种对象可以使用valueOf方法,使其变成原始类型。

2.对象转布尔

对象转布尔.png

3.对象转字符串和数字

相较于其他转化,这个最为复杂,我们来了解一下这个转化内部的过程。 首先流程是Ojbject=>ToPrimitive(input, String)

ToPrimitive(obj, PreferredType)//第一个参数是要转换的值;第二个参数是需要转换成的类型,只有Number,String,Boolean.

ToPrimitive(obj, Number)

  1. 如果obj是基本类型,直接返回
  2. else,调用 valueOf 方法,如果得到一个原始类型,则返回
  3. else,调用 toString 方法,如果得到一个原始类型,则返回
  4. else if报错

ToPrimitive(obj, String)

  1. 如果obj是基本类型,直接返回
  2. else,调用 toString 方法,如果得到一个原始类型,则返回
  3. else,调用 valueOf 方法,如果得到一个原始类型,则返回
  4. else if报错

通过上述流程就可以使对象变成原始类型,接下来通过之前讲的原始值转字符串,数字就可以得出最终答案。

toString,valueOf不是本次类型转换的重点,大家会使用就可以了,下面是相关的表。

toString,valueOf.webp

接下来就是两个例子运用了上面的规则。

Number([])
 ([]).value()//[]
([]).toString//''
Number('')//0


Number({})
 ({}).value()//[]
({}).toString//'[object Object]'
Number('[object Object]')//NaN


三. 操作符和隐式转换

关于1+‘1’等于什么相信大家都知道并使用过,等于‘11’,但是是为什么呢?

这是因为js是一种弱类型的编程语言,在进行上述操作时,会进行类型转换,而且是隐式转换,再在 + 操作符的一系列规则下,最终得出结果。

1.一元操作符 +

+['1']这个例子就是一元操作符 +

一元操作符 + 的规则就是让调用ToNumber(['1']),这也很好理解,毕竟 + 这种运算就是为数字而生的,所以就转换成数字。具体过程前面也讲了,Number(['1'])通过ToPrimitive(obj, Number)方法,使其变成字符串或者是数字,如果是字符串,则在多一步冲字符串转数字,最后的结果都是数字。

上面的例子的结果也就是数字1

再来一个例子+['1','2','3'],这个例子的结果或许与你想的不尽想同。结果可以放在评论区。

2. 二元操作符 +

v1 + v2

  1. lprim = ToPrimitive(v1)
  2. rprim = ToPrimitive(v2)
  3. 如果 lprim 是字符串或 rprim 是字符串,那么返回 ToString(lprim) 和 ToString(rprim)的拼接结果
  4. 返回 ToNumber(lprim) 和 ToNumber(rprim)的相加结果

这样1+‘1’的结果就显而易见了。

3. ==

x == y

1). 如果 x 和 y 是同一类型

1).  x 是 Undefined,返回true

(2). x 是 null,返回true

(3). x 是数字

    1.  x 是 NaN ,返回 false

(4). x和y指向同一个对象,返回true,否则返回false

2). null == undefined // true

3). 1 == 'h' // ToNumber('h')

4). false == '1' // ToNumber(false) ToNumber('1')

5). true == {a: 1} // ToPrimitive({a: 1})