数据类型转换看这篇就够了

简介: 日常开发中,我们使用到的Js定义的每一个值都属于某一种数据类型,常见的js数据类型有String(字符串)、Number(数字)、Boolean(布尔)、Object、Undefined、Null、Symbol等等,其中Symbol是ES6引入的新的数据类型,表示独一无二的数值。因为 JS 本身是一门弱类型语言,以至于类型转换发生的频繁很高,本文旨在帮助大家梳理各种类型之间的相互转换,在每一小节讲解转换前,还会跟大家介绍这些“老朋友”

微信截图_20220512152325.png

日常开发中,我们使用到的Js定义的每一个值都属于某一种数据类型,常见的js数据类型有String(字符串)、Number(数字)、Boolean(布尔)、Object、Undefined、Null、Symbol等等,其中Symbol是ES6引入的新的数据类型,表示独一无二的数值。因为 JS 本身是一门弱类型语言,以至于类型转换发生的频繁很高,本文旨在帮助大家梳理各种类型之间的相互转换,在每一小节讲解转换前,还会跟大家介绍这些“老朋友”


数据转换分为显示转换和隐式转换


  • ☀️显示转换:常见的️显式转换方法有:Boolean()、Number()、String()等等
  • 🌛隐式转换:常见的隐式转换方法:四则运算(加减乘除) 、== 、判断语句(if)等


1.String


String是存储字符的变量,String使用长度属性length来计算字符串的长度


1.1 String转换为Number


  • parseInt(string, 10)


parseInt() 函数可解析一个字符串,从位置 0 开始查看每个字符,直到找到第一个非有效的字符为止,最后并返回一个整数。


parseInt() 方法还有基模式,可以把二进制、八进制、十六进制或其他任何进制的字符串转换成整数。基是由 parseInt() 方法的第二个参数指定的


微信截图_20220512152335.png


  • parseFloat(string)


相比上一节parseInt函数是将值转换成整数,parseFloat函数则是将值转换成浮点数且该方法方法也没有基模式(转换不了),只有对 String 类型调用这些方法,它们才能正确运行


微信截图_20220512152348.png


  • Number(string)


Number() 函数的强制类型转换与 parseInt() 和 parseFloat() 方法的处理方式相似,只是它转换的是整个值,而不是部分值


上两节提到的parseInt() 和 parseFloat() 方法只转换第一个无效字符之前的字符串,因此 "1.2.3" 将分别被转换为 "1" 和 "1.2"。 而用Number() 进行强制类型转换,"1.2.3" 将返回 NaN,因为整个字符串值不能转换成数字。如果字符串值能被完整地转换


微信截图_20220512152400.png


  • + string


通过在字符串前面加了个加号,这个数值就变成了number类型


微信截图_20220512152412.png


1.2  String转Object


通过JSON.parse来完成,该注意的是JSON.parse遇到不可解析的字符串时,会抛出SyntaxError异常。


微信截图_20220512152423.png


1.3  String转Object(Array数组类型)


微信截图_20220512152433.png


2.Number


Number类型是以IEEE-754标准格式来表示的,包括整数和浮点数,如果是计算会转化为2进制再计算,这也是0.1 + 0.2不等于0.3的原因


拓展:为什么在 JavaScript 中,0.1+0.2 不等于 0.3:


console.log( 0.1 + 0.2 == 0.3);  //false


因为在JavaScript中的二进制的浮点数0.1和0.2并不是十分精确,在他们相加的结果并非正好等于0.3,而是一个比较接近的数字 0.3000000x ,所以条件判断结果为false。


问题:有没有方法可以解决上述问题呢❓ 可以使用 JavaScript 提供的最小精度值

Number.EPSILON,在这个误差的范围内就可以判定0.1+0.2===0.3为true,如下👇所示


微信截图_20220512152442.png


多数情况下,Number 比 parseInt 和 parseFloat 等方法会更好


2.1 Number转String


  • n.toString( )


toString() 方法把数字转换成指定进制形式的字符串。


微信截图_20220512152452.png


  • 一元运算符 +


通过在数字后面加了个空字符串,这个数值就变成了string类型


微信截图_20220512152501.png


2.2 Number转Boolean


number类型转Boolean,除了0数值和NaN对应的是false,其他数值都对应true


微信截图_20220512152512.png


3.Boolean


Boolean 类型有且只有两种值:true和false,主要用来表示逻辑意义上的真和假 boolean 这个类型比较简单,这里就不做复杂介绍


除了下面六个值被转为false,其他都为true


微信截图_20220512152523.png


4.Object


Object对象是js中比较复杂的数据类型,涉及的东西比其他类型都多,简单描述对象的话,可以说是由key-value聚合的数据集合,即属性的集合。JS对象主要可以分为两大类,分别是内置对象和宿主对象


  • 内置对象: JS内置对象也被定义为内部类,换句话说就是JavaScript里面封装好了的类,内部类大致有:Array,Boolean,RegExp,Date,Math,Number,String,也就是我们平时看到的 如 new Date();


  • 宿主对象: JS所运行的环境提供的对象如:BOM中的Window、DOM中的document

数组(Array)、日期(Date)、null等的数据类型都是 object


这里也介绍不同类型对象toString()方法的返回值


微信截图_20220512152534.png


注意:比如 10 与 new Number(10) 是两个不同的值,前者是 Number 类型, 后者是对象类型


再举个列子比如 new Date 与 Date(),虽然得出结果一样,但内置对象 Date 作为构造器new 将产生新的对象,而作为函数时,则产生字符串,如下所示👇


微信截图_20220512152545.png


4.1 Object转为String


微信截图_20220512152554.png


4.2 Object对象转Object数组


对象转数组方式很多,其中包括以下几种👇


  • Object.values(object):返回一个对象所有可枚举属性对应数值组成的数组
  • Object.keys(object): 返回一个对象的自身可枚举属性组成的数组
  • Object.entries(object):返回一个给定对象自身可枚举属性的键值对数组


微信截图_20220512152603.png


如果类数组对象或者可遍历的对象要转换,还可以用Array.from()方式,不过前提是object中必须有length属性,返回的数组长度取决于这个object中length长度,同时object的key值必须是数值


微信截图_20220512152611.png


小朋友👦👧你是否有很多问号❓类对象是啥?


类数组对象你可以看做一种“伪数组”,虽然它无法调用数组的方法,但是具备length属性,可以索引获取内部项的数据结构


4.3 日期Object转Number


将日期对象转换为数字(时间戳的形式),可以通过Number() 或者日期方法 getTime()


微信截图_20220512152622.png


4.4 数组Object转String


通过join或toString()的方法,join()可以指定分隔符,如果不加参数,则默认使用逗号作为分隔符,与 toString() 方法转换操作效果相同


微信截图_20220512152629.png


通过[1,2,3,4]初始化与new Array()作用一样,也是创建了一个对象,新建的对象a.proto == Array.prototype


5 Undefind和Null


两者都是JavaScript语言用来表示"无"的值,且两者有共同点也有不同点,共同点在于都只有一个值,Null只有一个值 null,Undefined也只有一个值undefined。不同点在于Null 表示为‘定义了但是值为空’,而Undefind 表示为'这里应该有一个值,但是还没有定义'


要注意的是,如果我们用typeof来判断null的类型,会判定为 Object 类型,而不是Null类型只是为什么呢?


是因为JavaScript 数据类型在底层都是以二进制的形式表示的,二进制的前三位为 0 会被 typeof 判断为对象类型,而 null 的二进制位恰好都是 0 ,因此,null 被误判断为 Object 类型。此时我们可以用上一节谈到的通过Object上的 原型上的toString()方法,如下👇 Object.prototype.toString.call(null) //[object Null]来区分


5.1 Undefind和Null转Number


undefined无法转为数字、而Null被转换为0


微信截图_20220512152640.png


再看一个例子👇


微信截图_20220512152653.png


undefined无法转为数字,第一个调用返回NaN.第二个是null转为隐式转换为0所以是2 ,第三个是如果传入的参数是undefined会以默认值为准,所以是3


5.2 总结


  • 不要对一个显式变量的赋值 undefined,当需要释放一个对象时,直接赋值为 null 即可


  • == 双等号中如果两个值类型不同,也有可能相等,undefind == null就是其中一个,包括 1 == '1',但是如果null与undefined与其他数相等运算时就不行,因为它们不进行类型转换(隐式转换)


6.Symbol


Symbol是ES6新引入的数据类型,表示独一无二的值,类似于一种标识唯一性的ID,Symbol 函数不同的是,直接用new 调用它会抛出错误,因为生成的是原始类型值,不是对象,是 Symbol 对象的构造器。下面简单用一个例子就能告诉你如何独一无二👇


微信截图_20220512152705.png


symbol不能与其他类型的值进行运算,会报错(即不能隐式转换),但是部分可以显示转换为字符串或者布尔值


微信截图_20220512152714.png


7.拓展


7.1 类型判断方法


因为类型识别中,如果使用 typeof 来判断数据类型,只能区分基本类型,即 number、string、undefined、boolean、object、function、symbol这几种,但是对于数组、null、对象这些来说,使用 typeof 都会统一返回 “object” 。这时候就需要用到其它方式👇


通过Object.protptype.toString.call()截取字符串[object...]中间字符串来区分类型,去掉前后符号,比如 "[object Array]"就提取了array来判断,之前写的工具库有定义点我👉


微信截图_20220512152724.png


那直接用 Object.prototype.toString(1) 可以吗?答案是不行的,因为考虑到为了每个对象都能通过,所以才需要以 Function.prototype.call()的形式来调用,传递要检查的对象作为第一个参数


微信截图_20220512152733.png


在举个例子,看如下👇


微信截图_20220512152741.png


为什么Object.prototype和Array.protoType是两个结果? 这里涉及到一些原型链的问题,这里也大概讲一下


首先js中对象大多继承自Object,当在某个对象上调用方法时,会先优先在该对象上进行查找,如果没找到则会进入对象的原型(也就是.prototype)进行探索,如果还是没找到这个方法,同样的也会进入对象原型的原型进行查找,直到找到或者进入原型链的顶端Object.prototype为止。


所以,比如它调用的是Array.prototype.toString,虽然Array也继承自Object,但js在Array.prototype上重写了toString,所以导致结果不同,而第三个例子toString(),因为本身调用的是Array.prototype.toString,所以结果是跟第二种方式一致。


总结:只有Object.prototype上的toString才能用来进行复杂数据类型的判断


往期文章




相关文章
|
4天前
|
存储 C语言
【C 言专栏】C 语言中的数据类型详解
【4月更文挑战第30天】本文介绍了C语言中的核心数据类型,包括整型(short, int, long, long long)、浮点型(float, double)、字符型(char)、指针、数组、结构体、共用体和枚举。理解这些类型的特点和适用场景对于编写高效准确的C语言代码至关重要。选择合适的数据类型并注意转换和运算规则,能避免错误,为编程打下坚实基础。
|
4天前
|
存储 安全 C语言
【C数据(一)】数据类型和变量你真的理解了吗?来看看这篇
【C数据(一)】数据类型和变量你真的理解了吗?来看看这篇
|
4天前
|
存储 安全 编译器
【C++ 隐式转换】探究C++中隐式转换的奥秘
【C++ 隐式转换】探究C++中隐式转换的奥秘
93 0
|
7月前
|
安全 编译器 C语言
C++进阶 类型转换
C++进阶 类型转换
32 1
|
8月前
|
存储 C++ Windows
第二章:数据类型
第二章:数据类型
28 0
|
9月前
|
存储 编译器 C语言
C语言数据类型类型及语句(各种详细的细节以及基础+持续更新中
C语言数据类型类型及语句(各种详细的细节以及基础+持续更新中
176 0
C语言数据类型类型及语句(各种详细的细节以及基础+持续更新中
|
11月前
|
开发框架 .NET 编译器
【C#本质论 二】数据类型
【C#本质论 二】数据类型
60 0
|
11月前
|
存储 Java 编译器
【C#本质论 三】更多数据类型
【C#本质论 三】更多数据类型
48 0
|
11月前
|
安全 编译器 程序员
【C++知识点】类型转换
【C++知识点】类型转换
113 0
|
存储 编译器 C++
C++ primer 复习 第二章变量和基本类型 2.1 C++ 数据类型
C++ primer 复习 第二章变量和基本类型 2.1 C++ 数据类型
C++ primer 复习 第二章变量和基本类型 2.1 C++ 数据类型