上一期中我们主要是了解了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的规则进行运算。
以上内容虽然有进行验证,但不知道描述上是否存在歧义,有些点表述的不是很清楚,望谅解。
如果有发现任何问题或者有更好的建议,欢迎直接给我留言。
领取专属 10元无门槛券
私享最新 技术干货