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

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

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

ToPrimitive 方法

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

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

type 的值

当 type 为 number 时规则

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

当 type 为 string 时规则

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

两者的主要区别

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

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

总结

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

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

基本类型在不同操作符的情况下隐式转换的规则

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

+ 操作符

+ 操作符的两边有至少一个 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

-、 *、 \ 操作符

NaN 也是一个数字:

1 * '23' // 23
1 * false // 0
1 / 'aa' // NaN

对于 == 操作符

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

3 == true // false, 3 转为number为3, true转为number为1
'0' == false //true, '0'转为number为0, false转为number为0
'0' == 0 // '0'转为number为0

对于 < 和 > 比较符

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

'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]"

相关文章:

  • 【面试题】2022前端面试真题
  • TIA博途V17中ProDiag功能的使用方法示例(二)可编辑的文本框
  • SSM学生健康防疫信息管理毕业设计-附源码041613
  • 使用node.js创建一个todo列表——node.js服务器搭建以及json读写
  • 如何通过经纬度坐标获取附近的地址信息?
  • LNMP+Redis
  • 记一次java组装elementPlus的TreeSelect树形菜单的数据结构
  • springboot基于web模式的师资管理系统的设计与实现毕业设计源码040928
  • 计算机复试面试题总结
  • 计算机二级--java篇
  • Vue.js核心技术解析与uni-app跨平台实战开发学习笔记 第10章 Vuex状态管理 10.4 actions的使用
  • 玩转 uniapp 全端开发
  • 【AGC】云存储如何上传文件?是否可以自行开通?云存储的相关问题,来这里看看!
  • 新款FTP替代系统重磅登场!怎样摆脱传统FTP弊端?
  • 页面引擎之velocity的基础入门学习
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 《Java编程思想》读书笔记-对象导论
  • AngularJS指令开发(1)——参数详解
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • js如何打印object对象
  • Markdown 语法简单说明
  • PHP 7 修改了什么呢 -- 2
  • Python进阶细节
  • 从伪并行的 Python 多线程说起
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 分享几个不错的工具
  • 构建工具 - 收藏集 - 掘金
  • 精彩代码 vue.js
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 使用docker-compose进行多节点部署
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 我与Jetbrains的这些年
  • 项目实战-Api的解决方案
  • 新书推荐|Windows黑客编程技术详解
  • 用Visual Studio开发以太坊智能合约
  • Android开发者必备:推荐一款助力开发的开源APP
  • !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
  • #NOIP 2014# day.2 T2 寻找道路
  • (C语言)fgets与fputs函数详解
  • (C语言)球球大作战
  • (LeetCode) T14. Longest Common Prefix
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (TOJ2804)Even? Odd?
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (一)UDP基本编程步骤
  • (正则)提取页面里的img标签
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .NET Framework .NET Core与 .NET 的区别
  • .net FrameWork简介,数组,枚举