js中的基本类型
基本类型:number(只可以表示2的53次方-1),string,boolean,undefined,null,symbol,bigint(基于数组方式表示)
引用类型:Object, Array, Function, Date, RegExp, Map/Set/WeakMap/WeakSet (ES6+)
判断js的类型有以下几种方法
一、typeof判断法(基本类型判断)
通过上面的输出我们可以发现:typeof可以判断除了null以外的其他类型基本数据,
typeof判断引用数据类型,除了function 以外,其他的都返回object。
实现原理:typeof是通过将值的转化为二进制数来判断类型的,二进制的前三位为0那么就识别为对象,null的二进制全是0故判断为对象类型。
二、Instanceof(引用类型判断)
在理解 instanceof 之前,必须明确两个关键概念:
1.显式原型 (prototype):
- 是构造函数特有的属性
- 指向该构造函数创建的实例对象的原型对象
- 例如:Array.prototype 是所有数组实例的原型
2.隐式原型 (proto):
- 是每个对象都有的属性
- 指向创建该对象的构造函数的 prototype
- 现代代码中建议使用 Object.getPrototypeOf() 替代 proto
Instanceof方法本质上是判断左边的隐式原型是不是右边的显示原型。如果不是则继续判断左边隐式原型的隐式原型,一直判断下去,直到两边相等或者左边的值已经为null了。嘿嘿嘿,都知道原理了手搓一个代码不过分吧。
手搓Instanceof方法
function myInstanceof(L,R){
L=L.__proto__
while(L){
if(L==R.prototype){
return true
}
L=L.__proto__
}
return false
三、Object.prototype.toString(任何类型)
Object.prototype.toString( ) 是 JavaScript 中用于检测对象类型的核心方法。它可以精确返回任意值的内部 [[Class]] 属性(格式为 [object Type])。
与 typeof
和 instanceof
的对比
方法 | 特点 |
---|---|
typeof | 无法区分对象类型(如 Array 、Date 均返回 "object" ) |
instanceof | 受原型链影响,跨窗口/iframe 时会失效 |
Object.prototype.toString | 最可靠,能精确识别内置类型(包括 Null 和 Undefined ) |
小小判断题
在进一步了解我们的判断之前我们先区分一下==与====
1.==会发送隐式类型转化,所以只判断值是不是相等的
2.===不会发生类型转化,所以只会判断值和类型是不是相等的
这是因为==发生的隐式转化,所以只判断值是否相等,故第一个输出的结果为true,但是第二个===不发生类型转化,数字类型与string类型显然是不相等的嘛。
隐式转化与显式转化
通俗的来说隐式转化也就是我们看不到的类型转化,由js引擎自动完成,开发者不直接转换代码。 显示转化也就是写出来的转化,是开发者主动调用的类型转化。引用类型可以转化为原始类型 这个是基于目的来的,因为我们的判断主要是四则运算这些,四则运算又是判断基本的数据类型。 但是原始类型是不可以转化为引用类型的
一、原始类型转原始类型
valueOf()
出现在对象的原型上面,只能将包装类的对象转化为原始类型。
toString()
js中的大部分构造函数原型上面都重写了toString方法
- {}.toString返回由
- [].toString 返回由数组中的每个元素以逗号拼接而成的字符串
- xxx.toString 直接返回xxx的字符串字面量
二、引用类型转原始类型
1. 转布尔----任何引用类型转布尔都是true
2.转字符串--Stirng(obj)==>ToString(obj)==>Toprimitive(obj,string)
Toprimitive(obj,string)
- 判断obj是否为原始数据类型,若是则直接返回
- 否则,调用toString(),如果得到的是原始类型则返回
- 否则,调用valueOf(),如果的到的是原始类型则返回
- 否则,抛出TypeError的错误
3.转数字——Number(obj)==>ToNumber(obj)==>Toprimitive(obj,Number)
Toprimitive(obj,Number)
- 判断obj是否为原始数据类型,若是则直接返回
- 否则,调用valueOf(),如果的到的是原始类型则返回
- 否则,调用toString(),如果得到的是原始类型则返回
- 否则,抛出TypeError的错误
经典面试题
console.log(1==[]);
类型不同触发隐式转换
比较 number == array,需要将数组转为原始值
执行 ToPrimitive([], 'number')
检查 Symbol.toPrimitive:数组没有定义 → 跳过
调用 valueOf():[].valueOf() 返回数组本身(非原始值)→ 继续
调用 toString():[].toString() 返回空字符串 ""
得到 Number("")
空字符串转为数字是 0
最终比较 1 == 0
结果为 false
console.log([]==![]);
![] 取反运算
[] 在布尔上下文中转为 true(所有对象转布尔都是 true)
!true 结果为 false
现在表达式变为:[] == false
false 转数字
根据规则:boolean 在 == 比较时会先转 number
Number(false) → 0
现在表达式变为:[] == 0
[] 转原始值
调用 [].valueOf() → 返回 [](仍是对象,继续转换)
调用 [].toString() → 返回 ""(空字符串)
现在表达式变为:"" == 0
"" 转数字
Number("") → 0
最终比较:0 == 0 → true