当前位置: 首页 > news >正文

11.JavaScript 中如何进行隐式类型转换?

首先要介绍ToPrimitive方法,这是 JavaScript 中每个值隐含的自带的方法,用来将值 (无论是基本类型值还是对象)转换为基本类型值。如果值为基本类型,则直接返回值本身;如果值为对象,其看起来大概是这样:

/**
* @obj 需要转换的对象
* @type 期望的结果类型
*/
ToPrimitive(obj,type)

type的值为number或者string

(1)当typenumber时规则如下:

  • 调用objvalueOf方法,如果为原始值,则返回,否则下一步;
  • 调用objtoString方法,后续同上;
  • 抛出TypeError 异常。

(2)当typestring时规则如下:

  • 调用objtoString方法,如果为原始值,则返回,否则下一步;
  • 调用objvalueOf方法,后续同上;
  • 抛出TypeError 异常。

可以看出两者的主要区别在于调用toStringvalueOf的先后顺序。默认情况下:

  • 如果对象为 Date 对象,则type默认为string
  • 其他情况下,type默认为number

总结上面的规则,对于 Date 以外的对象,转换为基本类型的大概规则可以概括为一个函数:

var objToNumber = value => Number(value.valueOf().toString())
objToNumber([]) === 0
objToNumber({}) === NaN

JavaScript 中的隐式类型转换主要发生在+、-、*、/以及==、>、<这些运算符之间。而这些运算符只能操作基本类型值,所以在进行这些运算前的第一步就是将两边的值用ToPrimitive转换成基本类型,再进行操作。

以下是基本类型的值在不同操作符的情况下隐式转换的规则 (对于对象,其会被ToPrimitive转换成基本类型,所以最终还是要应用基本类型转换规则):

  1. +操作符 +操作符的两边有至少一个string类型变量时,两边的变量都会被隐式转换为字符串;其他情况下两边的变量都会被转换为数字。
1 + '23' // '123'1 + false // 1 1 + Symbol() // Uncaught TypeError: Cannot convert a Symbol value to a number'1' + false // '1false'false + true // 1
  1. -*\操作符

NaN也是一个数字

1 * '23' // 231 * false // 01 / 'aa' // NaN
  1. 对于==操作符

操作符两边的值都尽量转成number

3 == true // false, 3 转为number为3,true转为number为1
'0' == false //true, '0'转为number为0,false转为number为0
'0' == 0 // '0'转为number为0
  1. 对于<>比较符

如果两边都是字符串,则比较字母表顺序:

'ca' < 'bd' // false
'a' < 'b' // true

其他情况下,转换为数字再比较:

'12' < 13 // true
false > -1 // true

以上说的是基本类型的隐式转换,而对象会被ToPrimitive转换为基本类型再进行转换:

var a = {}
a > 2 // false

其对比过程如下:

a.valueOf() // {}, 上面提到过,ToPrimitive默认type为number,所以先valueOf,结果还是个对象,下一步
a.toString() // "[object Object]",现在是一个字符串了
Number(a.toString()) // NaN,根据上面 < 和 > 操作符的规则,要转换成数字
NaN > 2 //false,得出比较结果

又比如:

var a = {name:'Jack'}
var b = {age: 18}
a + b // "[object Object][object Object]"

运算过程如下:

a.valueOf() // {},上面提到过,ToPrimitive默认type为number,所以先valueOf,结果还是个对象,下一步
a.toString() // "[object Object]"
b.valueOf() // 同理
b.toString() // "[object Object]"
a + b // "[object Object][object Object]"

相关文章:

  • 2024年华为OD机试真题-计算面积-Python-OD统一考试(C卷)
  • C语言静态库深入剖析
  • Apache Kafka: 强大消息队列系统的介绍与使用
  • OpenGL-ES 学习(1)---- AlphaBlend
  • nodejs学习计划--(十)会话控制及https补充
  • mysql全国省市县三级联动创表sql(一)
  • STM32之定时器
  • BTC破5W+QAQ
  • Windows 平台下NDK/CMAKE编译自己程序命令行
  • HarmonyOS 鸿蒙 ArkTS ArkUI 页面之间切换转换动画设置
  • 基于微信小程序的校园失物招领小程序
  • ajax函数库axios基本使用
  • Go语言从基础到高级-目录
  • 常用调试方法
  • Java奇缘:林浩然与杨凌芸的数学冒险记
  • 【译】JS基础算法脚本:字符串结尾
  • @jsonView过滤属性
  • 【5+】跨webview多页面 触发事件(二)
  • 4个实用的微服务测试策略
  • IndexedDB
  • input实现文字超出省略号功能
  • leetcode388. Longest Absolute File Path
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • React组件设计模式(一)
  • 翻译--Thinking in React
  • 类orAPI - 收藏集 - 掘金
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 事件委托的小应用
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 问题之ssh中Host key verification failed的解决
  • 详解移动APP与web APP的区别
  • Semaphore
  • ​secrets --- 生成管理密码的安全随机数​
  • !$boo在php中什么意思,php前戏
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #DBA杂记1
  • #Ubuntu(修改root信息)
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (1)(1.9) MSP (version 4.2)
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (windows2012共享文件夹和防火墙设置
  • (层次遍历)104. 二叉树的最大深度
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (附源码)计算机毕业设计高校学生选课系统
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • ***原理与防范
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .sys文件乱码_python vscode输出乱码
  • /bin/rm: 参数列表过长"的解决办法
  • @modelattribute注解用postman测试怎么传参_接口测试之问题挖掘