数据类型在js中是很重要的一部分,是必须掌握的基础中的基础,一定要掌握,面试中也是必考的内容之一。
一. 数据类型基础
数据类型有哪些
原始数据类型(又叫基本数据类型)
stringnumbernullundefinedbooleansymbolbigint
引用数据类型
object
判断数据类型的方法
判断基本数据类型:
typeof
// 可以判断除了null以外的所有原始数据类型
typeof 1 //number
判断引用数据类型: 常见的五种
Object.prototype.toString.call(obj)//通过Object的原型方法toString可以判断出数据类型 const type = Object.prototype.toString.call([]) // [object Array] type.slice(8, -1) // 'Array'- 注意:不能直接调用toString方法,因为有些对象的
原型上的toString已经被重写了,比如Array,Date,Function等,详见toString和Object.toString和Object.prototype.toString的区别
- 注意:不能直接调用toString方法,因为有些对象的
Object.prototype.isPrototypeOf(obj)// 判断调用者是否在原型链上 RegExp.prototype.isPrototypeOf(/test/) // true Array.prototype.isPrototypeOf(/test/) // falseinstanceof- instanceof的原理是
判断原型链上是否存在构造函数
// 只要在原型链上就会返回true 1 instanceof Array //false [] instanceof Array //true [] isntanceof Object //true- instanceof的原理是
obj.getPrototypeOf()- 原理是判断调用者是否在实例对象的原型链上
Array.prototpye.isPrototypeOf([]) // true Object.prototpye.isPrototypeOf([]) // true Function.prototpye.isPrototypeOf([]) // falseconstructor- 原理是对象可以通过constructor访问其构造函数来判断数据类型
- 注意:如果创建一个对象
改变了这个对象的原型,这个就不生效了,慎用
// const per = {a:1,b:2} per.constructor === Object // true // 改变实例隐式原型的指向 per.__proto__ = new Array() per.constructor === Object // false
判断数组:
Array.isArray([])- 上面的五种判断引用数据类型的方法都适用数组
数据类型的区别
存储位置
- 原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
- `引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。
- 关于堆栈的概念就不在本章中讲了,可以移步数据结构篇
包装类
基本数据类型是没有自己的属性的,所以正常是不能像对象一样去通过.的方式使用自己的方法和属性的,那为什么可以'abc'.length的呢,原来每个数据类型都有对应的包装类我们使用包装类的属性时js引擎会自动将基本数据类型转换为包装类,所以原始数据类型可以调用属性
二.类型转换
强制类型转换
引用数据类型转原始数据类型
Object.valueOf
基本数据类型之间的转换
- 可以通过对应的包装类构造函数去转换
const a = 1 String(a)//转字符串 Number(a)//转数字 Symbol(a)//转smyobl Boolean(a)//转布尔 toString(a)//转字符串 Bigint(a) //转bigint
隐式数据类型转换(重点)
== 操作符的转换规则
-
如果类型相同,调用
===操作符 -
如果类型不同,尝试类型转换
-
查看是否是
undefined和null比较
- ✅ 返回
true - ⬇️ 如果不是继续下一条规则
- 是否在比较
string和number
- ✅ 如果是,那么将
string转为number并回到最初重新比较 ♻️ - ⬇️ 如果不是继续下一条规则
- 查看我们比较的项中是否有
boolean
- ✅ 如果有,那么将
boolean转为number并回到最初重新比较 ♻️ - ⬇️ 如果不是继续下一条规则
- 查看是否有一项是
object
-
✅ 如果有,那么将
object转为其原始值primitive并回到最初重新比较 ♻️ -
❌ 如果还不是,只能返回
false了💩
引用数据类型转换原始数据类型规则
我们需要知道转换类型的这个方法在 JS 源代码中是
ToPrimitive这个方法,该方法有一个可选参数PreferredType,这个参数的作用是指定期望类型;如果第一个参数对应的对象可以被转换为不止一种类型,那么后者可以作为一种暗示,表示该对象应该转换为那种类型
-
默认情况下(期望类型默认为
number)-
调用
valueOf方法:- ✅ 如果返回的是原始值,那么就用这个
- ⬇️ 如果返回的不是原始值,那么跳到下一步
-
调用
toString方法:- ✅ 如果返回的是原始值,那么就用这个
- ❌ 否则报错💩
-
-
如果期望类型为
string:-
调用
toString方法:- ✅ 如果返回的是原始值,那么就用这个
- ⬇️ 如果返回的不是原始值,那么跳到下一步
-
调用
valueOf方法:- ✅ 如果返回的是原始值,那么就用这个
- ❌ 否则报错💩
-
-
如果对象是 Date 类型(期望类型为
string):-
调用
toString方法:- ✅ 如果返回的是原始值,那么就用这个
- ⬇️ 如果返回的不是原始值,那么跳到下一步
-
调用
valueOf方法:- ✅ 如果返回的是原始值,那么就用这个
- ❌ 否则报错💩
-
简单的说就是默认调用 valueOf 方法,然后是 toString 方法;如果对象是 Date 类型或对象的期望类型为 string,那么先调用 toString 方法
基本数据类型之间的转换规则
转换为 number
undefined👉NaN如果是 undefined 则直接转换成 NaNnull👉0如果是 null 则转换成 0boolean👉0/1如果是 boolean 则转换成 0 或 1string👉0/NaN/(parse to number)如果是 string 则转换成对应的 number,空字符串转换为 0,无法转换的则为 NaNobject👉 首先获取原始值然后再转为 number
转换为 string
undefined👉'undefined'null👉'null'number👉'numberboolean👉'true'/'false'object👉 首先获取原始值,然后转为 string
转为 boolean
undefined👉 falsy