JavaScript 隐式类型转换规则详解

 更新时间:2023年05月01日 11:10:15   作者:codinglin  
这篇文章主要为大家介绍了JavaScript 隐式类型转换规则详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪

前言

在 JavaScript 中,在进行运算操作时,如果两边数据不统一,这时我们编译器会自动将运算符两边的数据做一个数据类型转换再进行计算。这种由编译器进行自动转换的方式被称为隐式转换。

数学运算符中的类型转换

减、乘、除

在对非 Number 类型运用数学运算符(-*/)时,会先将非 Number 类型转换为 Number 类型再进行计算。示例如下:

2 - true  // 结果为 1,首先把 true 转换为数字 1,然后执行 2 - 1
2 - null  // 结果为 0,首先把 null 转换为数字 0,然后执行 2 - 0
2 - undefined  // 结果为 NaN,因为 undefined 被转换为 NaN,然后执行 2 - NaN
2 * '5'  // 结果为 10,'5' 首先会变成数字 5, 然后执行 2 * 5

注意:在算术运算中,如果操作数中有 undefined,其运算结果是就是 NaNnull 在算术运算中则是隐式转换为数值 0 来参与运算。

为什么加法要区别对待?因为 js 中 + 还可以用来拼接字符串。

加法运算遵守以下 3 条规则,优先级从高到低

当一侧为 String 类型,被识别为字符串拼接,并会优先将另一侧转换为字符串类型。

当一侧为 Number 类型,另一侧为原始类型,则将原始类型转换为 Number 类型。

当一侧为 Number 类型,另一侧为引用类型,将引用类型和 Number 类型转换成字符串后拼接。

示例如下:

123 + '123'  // 246 (规则1)
123 + null  // 123 (规则2)
123 + true  // 124 (规则2)
123 + undefined  // NaN (规则2)
123 + {}  // 123[object Object] (规则3)

逻辑语句中的类型转换

单个变量

如果只有单个变量,会先将变量转换为 Boolean 值。只有 nullundefined''NaN0false 这几个会被转换为 false,其他的情况都是 true,比如 {} , [] 等。示例如下:

if (null) {
  console.log('111')
} else {
  console.log('222')
}
// 输出 222

使用 == 比较

使用 == 比较,比较规则如下:

NaN 和其他任何类型比较永远返回 false(包括和它自己)。

Boolean 和其他任何类型比较,Boolean 首先被转换为 Number 类型。

StringNumber 比较,先将 String 类型转换为 Number 类型。

null == undefined 比较结果是 true,除此之外,nullundefined 和其他任何类型的比较都为 false

原始类型引用类型 比较时,引用类型会依照 ToPrimitive 规则转换为原始类型。(ToPrimitive 在下面有解释)

示例如下:

NaN == NaN  // false (规则1)

// (规则2)
true == 1  // true
true == '1'  // true
true == '2'  // false
true == ['1']  // true, 先把 true 变成 1, ['1'] 拆箱成 '1', 再参考(规则3)
true == ['2']  // false, 同上

// (规则3)
123 == '123'  // true
'' == 0  // true

// (规则4)
null == undefined  // true
null == ''  // false
null == 0  // false
null == false  // false
undefined == ''  // false
undefined == 0  // false
undefined == false  // false

// (规则5)
'[object Object]' == {}  // true, 字符串和对象比较,对象通过 toString 得到一个基本类型值
'1,2,3' == [1,2,3]  // true, 同上,[1,2,3] 通过 toString 得到一个基本类型值

ToPrimitive

ToPrimitive 规则会尝试调用对象的 valueOftoString 方法,将参数转换为原始类型。

当对象类型需要转为原始类型时,它会先查找对象的 valueOf 方法,如果 valueOf 方法返回原始类型的值,则 ToPrimitive 的结果就是这个值,如果 valueOf 不存在或者 valueOf 方法返回的不是原始类型的值,就会尝试调用对象的 toString 方法,也就是会遵循对象的 ToString 规则,然后使用toString 的返回值作为 ToPrimitive 的结果。

示例如下:

let str = new String(1)  // 通过 new String 创建了一个对象
console.log(typeof str)  // object
console.log(str.valueOf())  // "1"
console.log(typeof str.valueOf())  // string

const obj = {
  valueOf() {
    return 1
  },
  toString() {
    return 2
  }
}
console.log(Number(obj))  // 1

注意:如果 valueOftoString 都没有返回原始类型的值,则会抛出异常。

示例如下:

const obj = {
  valueOf() {
    return []
  },
  toString() {
    return {}
  }
}
console.log(Number(obj))  // TypeError: Cannot convert object to primitive value

特殊:

String({})  // [object Object]
Number([])  // 0

String({}) 空对象会先调用 valueOf,但返回的是对象本身 {},不是原始类型,所以会继续调用toString,得到 [object Object]String([object Object]),所以转换后的结果为 [object Object]

Number([]) 空数组会先调用 valueOf,但返回的是数组本身 [],不是原始类型,所以会继续调用toString,得到 '',相当于 Number(''),所以转换后的结果为 0

以上就是JavaScript 隐式类型转换规则详解的详细内容,更多关于JavaScript 隐式类型转换的资料请关注脚本之家其它相关文章!

相关文章

  • 本人自用的global.js库源码分享

    本人自用的global.js库源码分享

    这篇文章主要介绍了本人自用的global.js库源码分享,源码中包含常用WEB操作,如命名空间、DOM操作、数据判断、Cookie操作等功能,需要的朋友可以参考下
    2015-02-02
  • firefox插件Firebug的使用教程

    firefox插件Firebug的使用教程

    Firebug是Firefox下的一款开发类插件,现属于Firefox的五星级强力推荐插件之一。
    2010-01-01
  • 微信小程序实现顶部普通选项卡效果(非swiper)

    微信小程序实现顶部普通选项卡效果(非swiper)

    这篇文章主要为大家详细介绍了微信小程序实现顶部普通选项卡效果,非swiper,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • js删除数组中的元素delete和splice的区别详解

    js删除数组中的元素delete和splice的区别详解

    下面小编就为大家分享一篇js删除数组中的元素delete和splice的区别详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02
  • 浅谈如何循序渐进的学好JS

    浅谈如何循序渐进的学好JS

    如何才能学好JS?在这里给大家总结一些学习Js的经验,希望能对你们有所帮助。
    2021-05-05
  • js 上传文件预览的简单实例

    js 上传文件预览的简单实例

    下面小编就为大家带来一篇js 上传文件预览的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • js的es6常用新特性详解

    js的es6常用新特性详解

    ES6(ECMAScript 6,也称为ES2015)是JavaScript的一个重要更新版本,引入了许多新的语言特性和改进,使得JavaScript变得更加现代化、易读、易维护和更适合大型应用程序的开发,ES6的主要变化归纳为:语法糖、新机制、更好的语义、更多的内置对象和方法
    2023-11-11
  • js Dialog 实践分享

    js Dialog 实践分享

    在我们的WebApp项目中,Dialog是个不可或缺的元素,很多页面操作都通过Dialog来进行,今天我们就Dialog显示数据、提交数据做进一步分析
    2012-10-10
  • js遍历json对象所有key及根据动态key获取值的方法(必看)

    js遍历json对象所有key及根据动态key获取值的方法(必看)

    下面小编就为大家带来一篇js遍历json对象所有key及根据动态key获取值的方法(必看)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • 微信小程序 动态修改页面数据及参数传递过程详解

    微信小程序 动态修改页面数据及参数传递过程详解

    这篇文章主要介绍了微信小程序 动态修改页面数据及参数传递过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09

最新评论