JavaScript基础:手写实现typeof与instanceof

在这里插入图片描述

一、概念

1. typeof是一个运算符,有2种使用方式:typeof(表达式)和typeof 变量名,第一种是对表达式做运算,第二种是对变量做运算。typeof 操作符返回一个字符串,表示未经计算的操作数的类型。

可能的返回值:

  • “undefined”
  • “object”
  • “boolean”
  • “number”
  • “bigint”
  • “string”
  • “symbol”
  • “function”

注意:

typeof null === 'object';

查阅了相关的资料,其实这个是一个历史遗留的bug,在 javascript 的最初版本中,使用的 32 位系统,为了性能考虑使用低位存储了变量的类型信息:

  • 000:对象
  • 010:浮点数
  • 100:字符串
  • 110:布尔
  • 1:整数

但是, 对于 undefinednull 来说,这两个值的信息存储是有点特殊的。

null:对应机器码的 NULL 指针,一般是全零。

undefined:用 −2^30 整数来表示!

所以,typeof 在判断 null 的时候就出现问题了,由于 null 的所有机器码均为0,因此直接被当做了对象来看待。

2.instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

语法:

object instanceof constructor
// object 某个实例对象
// construtor 某个构造函数
3.Object.prototype.toString()
var toString=Object.prototype.toString;

console.log(toString.call(ndefined));  		// [object Undefined]
console.log(toString.call(null));  			// [object Null]
console.log(toString.call(true));  			// [object Boolean]
console.log(toString.call(666));  			// [object Number]
console.log(toString.call('前端收割机'));  	 // [object String]
console.log(toString.call({}));  			// [object Object]
console.log(toString.call([]));  			// [object Array]
console.log(toString.call(function(){}));  	// [object Function]
console.log(toString.call(new Date));  		// [object Date]
console.log(toString.call(new RegExp));  	// [object RegExp]
console.log(toString.call(new Error));  	// [object Error]
console.log(toString.call(arguments));  	// [object Arguments]

二、实现

1.优化版本typeof
console.log(typeof 6) //输出 number  
console.log(typeof null) //输出 object  
console.log(typeof {}) //输出 object  
console.log(typeof []) //输出 object 
console.log(typeof (new Date)) // 输出 object 
console.log(typeof (function(){})) //输出 function  
console.log(typeof undefined) //输出 undefined  
console.log(typeof '前端收割机') //输出 string  
console.log(typeof true)//输出 boolean

由上可得,typeof可以正确识别Undefined、Boolean、Number、String、Symbol、Function等数据类型,但是在数组,日期,对象上的判断确并不准确,都是返回object

优化版本实现代码:

/*
实现思路:
1.利用Object.prototype.toString()方法
2.将Object.prototype.toString()方法获取的字符串进行截取
3.利用toLowerCase()方法,将字符串转为小写
*/

function typeOf(obj) {    
	return Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
}

typeOf([]); 		// 输出 array 
typeOf({}); 		// 输出 object
typeOf(new Date); 	// 输出 date

2.实现instanceof
/*
实现思路:
1.leftVaule代表实例对象
2.rightVaule代表构造函数
3.利用typeof方法,判断输入的leftVaule是否为对象,如果不是,则返回false
4.遍历leftVaule的原型链,直到找到rightVaule的prototype,如果查找失败的话,返回false,反之,返回true
*/

function my_instanceof(leftVaule, rightVaule) {
    if(typeof leftVaule !== 'object' || leftVaule === null) return false;
    let rightProto = rightVaule.prototype,
        leftProto = leftVaule.__proto__;
    while (true) {
        if (leftProto === null) {
            return false;
        }
        if (leftProto === rightProto) {
            return true;
        }
        leftProto = leftProto.__proto__
    }
}

只要右边变量的prototype在左边变量的原型链上及可,也就是返回true。因此,instanceof在查询的过程中会遍历左边变量的原型链,直到找到右边变量的prototype,如果查找失败的话,返回false,告诉我们左边的变量并非是右边变量的实例。

三、总结

  • 使用 typeof 来判断基本数据类型是 ok 的,需要注意的是typeof判断null类型时的问题
  • 判断一个对象的话具体考虑用instanceof,但是instanceof判断一个数组的时候,它可以被instanceof判断为Obeject
  • 比较准确的的判断对象实例的类型,采取Object.prototype.toString.call()方法

参考连接:https://juejin.cn/post/6844904199700873223#heading-6

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值