还不了解js的隐式转换么???看了这篇文章你就懂了!

在我们日常的开发中总会用到大量的==、===、*、+、-等等符号,不过他们究竟是如何转换的,我们却不知道他的原理究竟是什么,接下来就带领大家探讨一下。

1、首先介绍一下大家所熟知的js的数据类型(原始数据类型和对象数据类型)

基础类型

number、bollean、string、null、undefined、symbol

复杂数据类型

object

2、 3种隐式类型转换

1、将值转为原始值,ToPrimitive()。
2、将值转为数字,ToNumber()。
3、将值转为字符串,ToString()。

隐式转换最关键的一点就是转换,什么是转换,如何转换,这就是个很重要的一点,比如在js中大家常常用到的的操作符号如+、==。

+可以是数字相加也可以是字符串相加、所以在转换的过程中就显得十分的麻烦,并且由于js中也存在==与===,这两种方式也有很大的不同。并且由于在js中也存在着-、*、/这几种运算符也就只能进行数字的运算,所以进行计算的参数究竟是如何运算转换的呢?

2.1、通过Toprimitive方法转换为原始值

在js中Toprimitive(input,preferedType?)的方法会有两个参数第一个未输入的值,第二个参数为想要转换的类型。

(1)如果类型为number时

1、如何输入的值是原始值,那么直接返回这个对象

2、如果输入值是一个对象的话,那么会调用这个对象的ValeOf()方法,如果是原始值则直接返回,否则的话调用tostring()这个方法,如果返回的的是原始值则直接返回,否则抛出异常TypeError。

(2)如果类型为String时

1、如何输入的值是原始值,那么直接返回这个对象

2、如果输入值是一个对象的话,那么会调用这个对象的tostring()方法,如果是原始值则直接返回,否则的话如果是个对象的时候,则调用对象的ValeOf()方法,如果是原始值则直接返回,否则抛出异常TypeError。

(3)如果没有类型参数时候

1、该对象为Date类型,则PreferredType被设置为String
2、否则,PreferredType被设置为Number

接下来解析一下valueOf方法和toString方法

在控制台输出Object.prototype,其中就有valueOf和toString方法,由于Object.prototype是所有对象原型链顶层原型,所有对象都会继承该原型的方法,所以对象都会有valueOf和toString方法。

valueOf究竟是如何转换的呢

1、Number、Boolean、String这三种构造函数生成的基础值的对象形式,通过valueOf转换后会变成相应的原始值。

如:var num = new Number(123)

      num.valueOf()    //123

2、Date为特殊格式,valueOf会转换为日期的毫秒形式

var a = new Date()

a.valueOf()   // 1626674425216

3、其他的数据返回的都为this,即对象本身

var a = new Array()

a.valueOf()  // []

ToString究竟是如何转换的呢

1、Number、Boolean、String、Array、Date、RegExp、Function这几种构造函数生成的对象,通过toString转换后会变成相应的字符串的形式,因为这些构造函数上封装了自己的toString方法。

var num = new Number('1asd');
num.toString(); // 'NaN'

var str = new String('12asd');
str.toString(); // '12asd'

var bool = new Boolean('fd');
bool.toString(); // 'true'

var arr = new Array(1,2);
arr.toString(); // '1,2'

var d = new Date();
d.toString(); // "Mon Jul 19 2021 14:04:00 GMT+0800 (中国标准时间)"

var func = function () {}
func.toString(); // "function () {}"

除这些对象及其实例化对象之外,其他对象返回的都是该对象的类型

var obj = new Object({});
obj.toString(); // "[object Object]"

Math.toString(); // "[object Math]"

2.2、ToNumber()将值转换为数字

参数转换
数字当前数字
undefinedNaN
null0
布尔值true:1  false:0
字符串位数字是是当前数字,否则NaN
对象

先进行 ToPrimitive(obj, Number)转换得到原始值,在进行ToNumber转换为数字

2.3、通过ToString将值转换为字符串

参数转换
数字123 > '123'
undefined’undefined‘
null’null‘
布尔值'true' 或 'false'
字符串本身
对象

先进行 ToPrimitive(obj, Number)转换得到原始值,在进行ToString转换为字符串

例子:

1、2 * {} = ?

首先 *只能运算基础类型,并且为数字,所以2不需要转换,此时 {} 需要进行转换

1、会对 {} 采用ToPrimitive(input, Number)运算。

2、首先会执行valueOf方法,({}).valueOf(),返回的还是{}对象,不是原始值。

3、然后toString方法,({}).toString(),返回"[object Object]",是原始值。

4、"[object Object]"再进行ToNumber运算,"[object Object]"就转换为NaN。

所以结果就是2 * NaN = NaN

在工作中运用到最多的就是== 与===,但是这个究竟是什么原理呢?

== 运算符的规则并不是特别强,例如 :

x == y,会根据x、y的值返回true 或者false。

(1)若x和y的类型相同

1、 若 Type(x) 为 Undefined, 返回 true。

2、 若 Type(x) 为 Null, 返回 true。

3、若 Type(x) 为 Number, 则

    (1)、若 x 为 NaN, 返回 false。(js规定NaN不等于本身)

    (2)、若 y 为 NaN, 返回 false。

    (3)、若 x 与 y 为相等数值, 返回 true。

    (4)、若 x 为 +0 且 y 为 −0, 返回 true。

    (5)、若 x 为 −0 且 y 为 +0, 返回 true。

    (6)、返回 false。

4、若 Type(x) 为 String, 则当 x 和 y 为完全相同的字符序列(长度相等且相同字符在相同位置)时返回 true。 否则, 返回 false。

5、若 Type(x) 为 Boolean, 当 x 和 y 为同为 true 或者同为 false 时返回 true。 否则, 返回 false。

6、当 x 和 y 为引用同一对象时返回 true。否则,返回 false。

 (2)若x和y的类型不相同

1、若 x 为 null 且 y 为 undefined, 返回 true。
2、若 x 为 undefined 且 y 为 null, 返回 true。
3、若 Type(x) 为 Number 且 Type(y) 为 String,返回比较 x == ToNumber(y) 的结果。
4、若 Type(x) 为 String 且 Type(y) 为 Number,返回比较 ToNumber(x) == y 的结果。
5、若 Type(x) 为 Boolean, 返回比较 ToNumber(x) == y 的结果。
6、若 Type(y) 为 Boolean, 返回比较 x == ToNumber(y) 的结果。
7、若 Type(x) 为 String 或 Number,且 Type(y) 为 Object,返回比较 x == ToPrimitive(y) 的结果。
8、若 Type(x) 为 Object 且 Type(y) 为 String 或 Number, 返回比较 ToPrimitive(x) == y 的结果。
9、返回 false。

例如  [] == !{}     ???

此时会根据规则并且算数符的优先级进行转换

1、! 运算符优先级高于==,故先进行!运算。
2、!{}运算结果为false,结果变成 [] == false比较。
3、根据规则,等式右边y = false =ToNumber(false) = 0。结果变成 [] == 0。
4、按照规则,比较变成ToPrimitive([]) == 0。
按照上面规则进行原始值转换,[]会先调用valueOf函数,返回this。
不是原始值,继续调用toString方法,x = [].toString() = ‘’。
故结果为 ‘’ == 0比较。
5、根据规则,等式左边x = ‘’ =ToNumber(’’) = 0。
所以结果变为: 0 == 0,返回true,比较结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值