instanceof和typeof 详解

本文详细探讨了JavaScript中的`typeof`和`instanceof`操作符。`typeof`对于基本数据类型判断准确,但对引用类型如Object、Array等判断不精确。而`instanceof`则用于判断构造函数的prototype是否存在于对象的原型链上,适用于引用类型,但对基本类型判断不准确。在处理多窗口交互时,`instanceof`可能出现问题。在需要精确判断数据类型时,应结合使用多种方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

判断变量是某种数据类型也是实际开发中常见的操作,总结如下:

写在前面

在介绍这两者之前先来回顾下js中的数据类型都有哪些。

  1. 基础数据类型
  • null
  • undefined
  • String
  • Number
  • Boolean
  1. 引用数据类型
  • Object、Array、Function、Date等
typeof

typeof操作符返回一个字符串,我们先来看看使用typeof判断数据类型的结果

typeof 10          // 'number'
typeof Number(10)  // 'number'
typeof NaN        // 'number'
typeof Infinity   // 'number'

typeof 'hello'           // 'string'
typeof String('hello')   // 'string'
typeof ''              // 'string'
typeof (typeof 10)      // 'string'

typeof true           // 'boolean'
typeof Boolean(true)  // 'boolean'

typeof undefined     // 'undefined'


typeof [1,2,3]              // 'object'
typeof {name: 'tom'}        // 'object'
typeof new String('hello')  // 'object'
typeof new Number(10)      // 'object'
typeof new Boolean(true)   // 'object'

typeof function(){}     // 'function'
typeof class C{}       // 'function'
typeof Math.sin        // 'function'
typeof new Function()  // 'function'


typeof /s/    // 'function';  Chrome 1-12 , 不符合 ECMAScript 5.1
typeof /s/   // 'object';  Firefox 5+ , 符合 ECMAScript 5.1


这是一个例外
typeof document.all   // 'undefined';

可以看出typeof对于基本数据类型的判断是值得信赖的,但是对于引用类型来讲并不是很友好,这里要特别说明一种情况:

typeof null    // 'object'

按照上述的逻辑来讲应该 也是null才对,官方给出的解释是:

在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null的类型标签也成为了 0,typeof null就错误的返回了"object"。

小结: 对于基本数据类型和function类型可以使用typeof来判断,对于引用类型的判断不是很精确。

instanceof

使用方法: instance instanceof constructor
判断规则: 判断constructor.prototype是否在instance的原型链上

// 定义构造函数
function C(){} 
function D(){} 

var o = new C();

o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype

o instanceof D; // false,因为 D.prototype不在o的原型链上

o instanceof Object; // true,因为Object.prototype.isPrototypeOf(o)返回true
C.prototype instanceof Object // true,同上

C.prototype = {};
var o2 = new C();

o2 instanceof C; // true

o instanceof C; // false,C.prototype指向了一个空对象,这个空对象不在o的原型链上.

D.prototype = new C(); // 继承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true 因为C.prototype现在在o3的原型链上

var str = new String('hello')
str instanceof String    // true
str instanceof Object    // true

这里有一个特例

var foo = function(){};
foo instanceof Object   // true
foo instanceof Function   // true

其实查看原型链的‘家谱图’后也不难解释。

对于引用类型的判断还是很友好的但是对于基本类型的判断就不是很友好了:

var test = 'hello', num = 100;
test instanceof String   // false
num instanceof Number    // false
test instanceof Object    // false
num instanceof Object     // false

这里有一种情况需要注意:

在浏览器中,我们的脚本可能需要在多个窗口之间进行交互。多个窗口意味着多个全局环境,不同的全局环境拥有不同的全局对象,从而拥有不同的内置类型构造函数。这可能会引发一些问题。比如,表达式 [] instanceof window.frames[0].Array 会返回false,因为 Array.prototype !== window.frames[0].Array.prototype

小结: 对于引用类型可以使用instanceof来判断,对于基础数据类型的判断不是很精确。

这时我们需要一种无论对于基本数据类型还是引用类型都可以精确判断的方法:

Object.prototype.toString.call('hello')  // "[object String]"

Object.prototype.toString.call(100)  // "[object Number]"

Object.prototype.toString.call(null)  // "[object Null]"

Object.prototype.toString.call(undefined)  // "[object Undefined]"

Object.prototype.toString.call([1,2,3])  // "[object Array]"
...

这种方法是最精确的判断数据类型的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值