数据类型
JavaScript中数据类型主要被分为两个大类:简单数据类型与引用数据类型
简单类型
- 常见简单类型:Number,String,Boolean,undefined,null,Symbol,Bigint
- 特点:不可向简单类型对象上添加属性与方法
引用类型
- 常见引用类型: Function,Array,Object,Set等等
- 特点:引用类型对象不直接保存对象的值,而是保存对象在堆中的地址
类型判断
使用typeof()函数判断类型
简单类型
null会被错误的判断为Object类型,除此之外的简单数据类型正常判断
引用类型
几乎所有引用类型都被判断为Object类型,Function除外
导致原因:古早的bug
关于typeof判断的原理:typeof 通过将数值转化为二进制的形式来判断类型
关于引用类型:引用类型数据的二进制前三位都为0,所以二进制前三位都为0的,会被判断成Object类型
关于 null:null转为二进制时,所有二进制位均为0,所以会被被typeof函数判断为Object类型
使用 instanceof 函数 判断类型
简单类型
都无法判断
引用类型
都可以判断
实现原理
通过隐式原型链的查找来判断x是否隶属于X这个类型 例子:明明 "[ ]" 是Array类型,但是却能够被成功判断为Object类型
原型链: instanceof 函数沿着 x对象的隐式原型链往上查找,直到找到X的显式原型
手搓 instanceof 函数
function myInstanceof(obj, OBJ) {
//因为 instanceof 函数无法判断原始类型,则自己打造的函数需要排除所有原始类型
if ((typeof (obj) == Object || typeof (obj) == 'function') && obj != null) {
while (obj.__proto__) { //沿着隐式原型链接向上查找
if (obj.__proto__ == OBJ.prototype) {
//函数
return true;
}
obj = obj.__proto__;
}
}
return false;
}
使用Object.prototype.toString.call() 判断对象类型
可以用于判断所有类型的数据
我们得到了 '[object Array]' 这一字符串,只要对其进行一定的处理便可以用于类型判断。
处理过程:
实现原理
官方原文
翻译:
- 如果传入值为undefined,则返回字符串"[object Undefined]".
- 如果传入值为null,则返回字符串"[object Null]".
- 将this值传递给ToObject函数,设 O 为调用 ToObject 的结果, 即 const o = ToObject(this)
- 设一个变量 class 为 O 内部属性[[class]]的属性值. 即 const class = O.[[class]] (class 值为 创建该对象 的 构造函数名)
- 最后返回一个字符串,该字符串由三部分组成 ['[object'+ class +']']
Object.prototype.toString.call() 中 call()的作用
我们可以先试一下如果没有call()函数会得到一个什么情况
明明传入的是个字符类型,但是函数却判断的是Object类型。因为toString函数中的this指向的是Object.prototype 对象。
call()函数的意义
call可以将toString内部的this绑定到传入的对象上
使用Array.isArray( )判断对象是否是数组类型
如何使用 Array.isArray(obj)
实现原理与手搓一个Array.isArray( )
原理
利用 obj.proto == Array.prototype 判断obj是否属于Array类型
Array.myIsArray = function (obj) {
if (obj) {
if (obj.__proto__ == Array.prototype) {
return true;
}
}
return false
}