instanceof 运算符

本文详细解释了JavaScript中instanceof运算符的用途及其工作原理,包括如何通过该运算符判断对象类型,解决typeof运算符在处理引用类型时的局限性,并深入探讨了instanceof在多层继承中的应用。

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

为什么要用 instanceof 运算符?

先来复习一下 typeof 怎么用的

console.log(typeof Array);
console.log(typeof Object);
console.log(typeof Number);

var arr = new Array();
console.log(typeof arr);

function Foo() {};
var foo = new Foo();
console.log(typeof foo);

function F() {};
F.prototype = Foo.prototype;
function childFoo() {};
childFoo.prototype = new F();
childFoo.prototype.constructor = childFoo;
var c = new childFoo();
console.log(typeof c);

在 JavaScript 中,判断一个变量的类型常常会用 typeof 运算符,在使用 typeof 运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 “object”。instanceof 运算符与 typeof 运算符相似,用于识别正在处理的对象的类型。与 typeof 方法不同的是,instanceof 方法要求开发者明确地确认对象为某特定类型。例如:

var arr = new Array(); 
console.log(arr instanceof Array);   // 输出 "true"

这段代码期望的作用是 arr 是否是 Array 的实例。在前面我们说过 typeof ,在typeof 只能返回 ‘object’ 的情况下,这段代码返回 true 还是比较有用的。

通常来讲,使用 instanceof 就是判断一个实例是否属于某种类型。例如:

// 判断 foo 是否是 Foo 类的实例
function Foo(){} 
var foo = new Foo(); 
console.log(foo instanceof Foo)//true

其实 instanceof 还可以用来判断一个实例是否属于它的父类型:

// 判断 foo 是否是 Foo 类的实例 , 并且是否是其父类型的实例
function Aoo(){} 
function Foo(){} 
Foo.prototype = new Aoo();//JavaScript 原型继承

var foo = new Foo(); 
console.log(foo instanceof Foo)//true 
console.log(foo instanceof Aoo)//true

instanceof 运算符适用于多层继承关系

你真的了解 instanceof 操作符吗?

console.log(Object instanceof Object);//true 
console.log(Function instanceof Function);//true 
console.log(Number instanceof Number);//false 
console.log(String instanceof String);//false 

console.log(Function instanceof Object);//true 

console.log(Foo instanceof Function);//true 
console.log(Foo instanceof Foo);//false

为什么 Object 和 Function instanceof 自己等于 true,而其他类 instanceof 自己却又不等于 true 呢?

要想从根本上了解 instanceof 的奥秘,需要从两个方面着手:
1,语言规范中是如何定义这个运算符的。
2,JavaScript 原型继承机制。

JavaScript instanceof 运算符代码:

function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
 var O = R.prototype;// 取 R 的显示原型
 L = L.__proto__;// 取 L 的隐式原型
 while (true) { 
   if (L === null) 
     return false; 
   if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true 
     return true; 
   L = L.__proto__; 
 } 
}

JavaScript 原型继承机制:

由其本文涉及显示原型和隐式原型,所以下面对这两个概念作一下简单说明。在 JavaScript 原型继承结构里面,规范中用 [[Prototype]] 表示对象隐式的原型,在 JavaScript 中用 __proto__ 表示,并且在 Firefox 和 Chrome 浏览器中是可以访问得到这个属性的,但是 IE 下不行。所有 JavaScript 对象都有 __proto__ 属性,但只有 Object.prototype.__proto__ 为 null,前提是没有在 Firefox 或者 Chrome 下修改过这个属性。这个属性指向它的原型对象。 至于显示的原型,在 JavaScript 里用 prototype 属性表示,这个是 JavaScript 原型继承的基础知识

JavaScript 原型链
prototype-constructor

instanceof 复杂用法

Object instanceof Object

// 为了方便表述,首先区分左侧表达式和右侧表达式
ObjectL = Object, ObjectR = Object; 
// 下面根据规范逐步推演
O = ObjectR.prototype = Object.prototype 
L = ObjectL.__proto__ = Function.prototype 
// 第一次判断
O != L 
// 循环查找 L 是否还有 __proto__ 
L = Function.prototype.__proto__ = Object.prototype 
// 第二次判断
O == L 
// 返回 true

Function instanceof Function

// 为了方便表述,首先区分左侧表达式和右侧表达式
FunctionL = Function, FunctionR = Function; 
// 下面根据规范逐步推演
O = FunctionR.prototype = Function.prototype 
L = FunctionL.__proto__ = Function.prototype 
// 第一次判断
O == L 
// 返回 true

Foo instanceof Foo

// 为了方便表述,首先区分左侧表达式和右侧表达式
FooL = Foo, FooR = Foo; 
// 下面根据规范逐步推演
O = FooR.prototype = Foo.prototype 
L = FooL.__proto__ = Function.prototype 
// 第一次判断
O != L 
// 循环再次查找 L 是否还有 __proto__ 
L = Function.prototype.__proto__ = Object.prototype 
// 第二次判断
O != L 
// 再次循环查找 L 是否还有 __proto__ 
L = Object.prototype.__proto__ = null 
// 第三次判断
L == null 
// 返回 false

__proto__ 在 IE Edge 版本以下(IE ≤ 10)的浏览器为 undefined

参考:
instanceof
https://www.ibm.com/developerworks/cn/web/1306_jiangjj_jsinstanceof/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值