instanceof 运算符

来源:互联网 发布:700套微信小游戏源码 编辑:程序博客网 时间:2024/05/20 05:05

为什么要用 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/

0 0