第2期:深入理解JavaScript数据类型转换

上一期中我们主要是了解了JavaScript中存在两大数据类型:和以及其存储的方式(堆和栈)。

本期我们将重点谈谈JavaScript数据类型转换过程出现的各种“奇葩”的问题。

写在前面

在JavaScript中当运算符在运算时,如果两边数据不统一,CPU就无法计算,这时我们编译器会自动将运算符两边的数据做一个数据类型转换,转成一样的数据类型再计算,这种无需程序员手动转换,而由编译器自动转换的方式就称为隐式转换

在JavaScript中“一切皆是对象”,在我们具体了解隐式转换前先了解一下对象的两个方法:和。

toString()

toString() 方法返回一个表示该对象的字符串。

valueOf()

valueOf() 方法返回指定对象的原始值。

JavaScript调用valueOf方法将对象转换为原始值。你很少需要自己调用valueOf方法;当遇到要预期的原始值的对象时,JavaScript会自动调用它。

默认情况下,valueOf方法由Object后面的每个对象继承。 每个内置的核心对象都会覆盖此方法以返回适当的值。如果对象没有原始值,则valueOf将返回对象本身。

JavaScript的许多内置对象都重写了该函数,以实现更适合自身的功能需要。因此,不同类型对象的valueOf()方法的返回值和返回值类型均可能不同。

隐式转换规则

转成string类型:+(字符串连接符)

转成number类型:++/--(自增或自减运算符)、+ - * / % (算术运算符)、> =

转成boolean类型:!(逻辑非运算符)

字符串 VS 加号连接符

字符串 + 基本类型 = 字符串 + String(基本类型)

数字 VS 加号连接符

数字 + 基本类型(非字符串) = 数字类型 + Number(基本类型)

数字 + 引用类型 = 数字 + 引用类型.toString()

数字类型 + 函数 = 数字类型 + String(函数)

关系运算符的隐式转换

规则:将其他数据类型转换成数字类型之后再比较关系

逻辑非与关系运算符的隐式转换

引用类型的隐式转换

规则:

当引用类型的valueOf()调用时返回的值是一个基本类型时,则直接进行运算。

当引用类型的valueOf()调用时返回的值不是一个基本类型时,则引用类型的toString()将会被调用并返回转换后的字符串,然后再进行运算。

案例一:

目的:验证非自定义对象的隐式转换过程

第一步:判断对象的valueOf()返回值是否是基本类型

第二步:调用对象的toString()返回一个表示该对象的字符串

第三步:根据运算规则进行运算(非字符连接操作都转换成Number进行运算)

案例二:

目的:通过自定义对象的valueOf()和toString(),来验证对象的隐式转换过程

第一步:判断对象的valueOf()返回值是否是基本类型

第二步:如果第一步能正确返回基本类型,则直接跳到第三步,否则将调用对象的toString()返回一个表示该对象的字符串

第三步:根据运算规则进行运算(非字符连接操作都转换成Number进行运算)

特殊说明

JavaScript中存在几个特殊的原始值:null、undefined、''、0、NaN。

写在最后

通过上面对JavaScript中的数据类型的隐式转换可以总结出以下结论:

JavaScript中运算符在运算时,最终都将转换成相同类型进行运算(字符串类型、数字类型)

字符串与加号连接符运算时转换成String类型

非字符串加号连接符的运算都将转换成Number类型

特别注意引用类型的隐式转换是先判断valueOf()返回的类型,如果返回是引用类型则调用toString()返回对应的字符串值,最终都是按照1,2,3的规则进行运算。

以上内容虽然有进行验证,但不知道描述上是否存在歧义,有些点表述的不是很清楚,望谅解。

如果有发现任何问题或者有更好的建议,欢迎直接给我留言。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190216G084TJ00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券