typeof 和 instanceof讲解以及最佳类型判断实践

说在前面

JavaScript作为前端当家的语言,其重要程度不言而喻,一些基础的语法以及概念之前经常有看,但是随看随忘,过程中有一些自己觉得惊鸿一瞥的发现也随着时间消失不见,特此开一个专题,把往往种种的体会分享出来,供自己回顾以及各位拿取。

开门见山

其实在阅读一些源码或者封装的代码时,经常会看到 使用 typeof 或者 instanceof来进行一些判断,有时不能很好地理解判断的具体含义,下面通过分析这两者的使用方式以及自身特性来加强理解。

typeof

语法: typeof operand 后面可以紧跟表示对象或者原始值的表达式,他会返回表达式的类型。

那么他判断的所有类型都是准确无误的嘛?或者说,他返回的类型都是我们想看到的吗?显然不是,比如JavaScript最初设计中的一个小“瑕疵”,

typeof null   // 'object'

我们不能说他错,但是我们在实际使用的过程中可不希望把null 判断成为一个object,因为这样会导致一些严重的错误。

用一句简单的话来说 typeof可以准确的判断结果不为 object的类型的数据,别急,后面我们会印证这个观点。

下面我们一起来看一下typeof关键字在判断类型时的一些表现:

typeof 37               // 'number'
typeof Nan              // 'number' 注意,特殊类型的number,not a number的number
typeof true             // 'boolean'
typeof '1'              // 'string'
typeof String('1')      // 'string'
typeof Symbol()         // 'symbol'
typeof undefined        // 'undefined'
typeof function() {}    // 'function'
typeof {a: 1}           // 'object'  一直到这里,所有得到的数据类型都是我们想得到的
------------------------------------------------我是分界线--------------------------------------------
var a = [1,2,3]
typeof a                // 'object', 数组是一种特殊的对象,判断是否为数组,需要使用Array.isArray方法
typeof null             // 'object' 可以通过 operand === null 判断是否为 null
typeof new Date()       // 'object'
typeof new String('a')  
// 'object',如果你打印过控制台的信息,你会看到得到的结果是 String {"a"},确实展示形式是对象,但是我们使用
// 过程中会将其理解为字符串(当然他在使用过程中和字符串无异,但是他在内存中确实是以String {"a"}存在)

从上述例子中可以看出typeof对于一些创建类型的数据(使用了new 关键字)都会返回 object,虽说返回了内存中正确的存在形式,但结果可能并不是我们想要得到的。所以说 typeof关键字,返回的不为 object类型的数据都是准确的,但是对于返回类型为 object 的数据,我们需要斟酌一下实际的结果。

延伸一刻:如果我们想判断一个数据表达式是否为object类型,要如何判断?

// we got a referance named a
if (typeof a !== null && typeof a === 'object') {
    return true
}

唉? 刚才不是说typeof 判断的类型为object的不准吗?怎么现在又这样写呢?其实根据上述结果,new String('123')虽然我们想得到的结果是string,但是说他是一个object却没有任何问题!

instanceof

语法: object instanceof constructor 用来检测constructor.protype 是否 存在于参数 object的原型链上。一定注意,后面跟的是一个构造函数。

一言以蔽之:可以准确判断复杂引用的数据类型,但不能正确判断基础数据类型。

var d = new Date()
d instanceof Date     // true
var s = new String('cctv')
s instanceof String   // true  s在控制台打印出来的结果是 String{"cctv"}
var str = 'cctv'
str instanceof String // false 这是怎么回事?  参见下方分析。
Object.getPrototypeOf(str) === String.prototype  
// true  确实符合了概念,看似存在于str的原型链上,但是str自身并不是一个 object

由此可以判断,instanceof在内部实现中,会判断 instanceof左侧是否为 object。如果不是,返回 false

再有,原型链是具有传递性的:

function C() {}

var o = new C();
o instanceof C  // true  Object.getPrototypeOf(o) === C.prototype
C.prototype instanceof Object  // true Object.getPrototypeof(C.prototype) === Object.prototype
o instanceof Object  // true  原型链的传递性

由此可以分析得出,原生js在实现 instanceof 的时候,会循环遍历左侧objectObject.getPrototypeOf('object')属性,并与 constructor.prototype进行对比,如果相等,则返回 true,如果不相等则继续排查,直到 Object.getPrototypeOf('object')的结果为 null 则返回 false

综上二者提出的概念,可以简单的实现一个 自己的instanceof,网上例子很多,这里不贴代码了,根据我的经验,贴上来代码大家很少会自己实践,just try it.

最佳类型判断实践

可曾听闻十三太保之 toString,这是个很神奇的方法,每个对象都继承了来自object的这个是属性,他可以被重写来完成一些特殊的任务,这里主要介绍他的默认用法,返回 [object class],其中class是该对象的类,可以为 Object,Number,Function,Date,Window,HTMLDocument等。

function getType(obj){
  // 对于typeof返回结果是object的,再进行如下的判断,正则返回结果
  return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1'); 
}
getType(window) // Window
getType(new Date()) // Date
getType(document)  // HTMLDocument

参考网站:

typeof - JavaScript | MDN

instanceof - JavaScript | MDN

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值