instanceof
概念
-
语法
object instaceof constructor // object为要测试的实例对象,constructor为构造函数
手写实现instanceof
步骤概念
由于instaneof是检测某个对象,所以传入数据必须是对象,才能进行下面的检测操作
- 左侧的proto 是否和右侧的prototype一致 (对象是否是构造函数的实例)
如果不一致,会一直向上找。直到找到为止,找到返回true,找不到返回false
function instance_of (L, R) {const baseType = ['string', 'boolean', 'number', 'undefined','Symbol']if (baseType.includes(typeof L)) return false // 检测某个对象if (L === null) return false // 检测某个对象L = L.__proto__let RP = R.prototypewhile(L) { // 无限循环if (L === null) return false // 找到最顶层,Object.prototype === null 返回falseif (L === RP) return true // 如果左侧的__proto__ 是否和右侧的prototype一致,返回trueL= L.__proto__ // 没找到继续向上一层原型链查找}}console.log(instance_of([], Array)) // trueconsole.log(instance_of('e', Array)) // falseconsole.log(instance_of(null, Object)) // false
function instance_of (L, R) {if (typeof L !== 'object' && typeof L !=== 'function') return false // 检测某个对象if (L === null) return false // 检测某个对象L = L.__proto__let RP = R.prototypewhile(L) { // 无限循环if (L === null) return false // 找到最顶层,Object.prototype === null 返回falseif (L === RP) return true // 如果左侧的__proto__ 是否和右侧的prototype一致,返回trueL= L.__proto__ // 没找到继续向上一层原型链查找}}console.log(instance_of([], Array)) // trueconsole.log(instance_of('e', Array)) // falseconsole.log(instance_of(null, Object)) // false
注意:
instancef玩的是原型链,你如果不是原型链的,当一个对象不是通过原型构造出来的,instanceof,就会失效 ```java function Fun(){} const f = new Fun() console.log(f instanceof Fun) // true
function Fun2(){return {}} const f2 = new Fun2() console.log(f2 instanceof Fun2) // false
<a name="HDpDt"></a># typeof<a name="dfF0S"></a>## 概念typeof返回一个字符串,表示未经计算的操作数的类型<a name="1O7B1"></a>## 历史发展:在很早之前,使用的32位系统,为了性能考虑使用低位存储了变量的类型信息.- 000 对象- 1 整数- 010 浮点数- 100 字符串- 110 布尔此外还有2个比较特殊的指: `undefined` 和 `null`- undefined 用 (-2^30) 表示- null 对应机器码的 NULL 指针,一般是全零这样一来,`null` 就出了一个bug.因为它对应的空指针,低位是000,因此被判断成一个对象了.且这个bug,应该是永远都不会去修复了。<a name="n2zLb"></a>## 可检测类型```javascriptconsole.log(typeof undefined) // undefinedconsole.log(typeof null) // objectconsole.log(typeof 123n) // bigintconsole.log(typeof Symbol('str')) // symbolconsole.log(typeof (() => {})) // functionconsole.log(typeof {}) // object
注意:
let 和 const 块级作用域后,在其被声明之前对块中的let 和 const 变量使用 typeof 将会抛出一个 ReferenceError
typeof类型检测终结解决方法
function getType (obj) {let type = Object.prototype.toString.call(obj)return type.split(' ')[1].replace(']', '')// Object.prototype.toString 会返回一个形如"[object XXX]"的字符串// split(' ') 将字符串用空格分隔,转化为数组}console.log(getType([]))
Object.prototype.toString 讲解
- Object.prototype.toString 会返回一个形如”[object XXX]”的字符串
- 对于Object.prototype.toString.call(arg),若参数为null或undefined,直接返回结果。
- 若参数不为null或undefined,则将参数转为对象,再作判断。对于原始类型,转为对象的方法即装箱,此处不赘述。
转为对象后,取得该对象的[Symbol.toStringTag]属性值(可能会遍历原型链)作为tag,如无该属性,或该属性值不为字符串类型,则依下表取得tag, 然后返回”[object “ + tag + “]”形式的字符串。
