instanceof 是如何工作的
知其然
JavaScript 提供 instanceof 关键字判断一个对象所属的构造函数。在 js 高级编程中讲到 instanceof 的作用:
instanceof 操作符,用来测试实例与原型链中出现过的构造函数,只要出现过就会返回 true。
个人对这句话不是很理解,看下面例子:
function Person(){
this.name="tjm";
}
function Student(){
Person.call(this);
this.grade = 1;
}
Student.prototype = new Person();
var stu = new Student();
console.log(stu instanceof Student); //true
console.log(stu instanceof Person); //true
首先要知道,每个构造函数在没显示指定原型的情况下,会默认分配一个原型对象,该原型对象中包含 constructor 属性指向构造函数,以及 prototype 属性指向 Object 的原型。但通过原型继承,显示指定 Student.prototype = new Person() , 那么构造函数 Student 的原型是 Person 对象,而该原型有一个 prototype 属性指向 Person 构造函数的原型,一个name 等于 tjm 的属性。因此,可以看出,stu 实例的原型链中并没有出现 Student 构造函数,但是stu instanceof Student 依然返回 true,这就让我感到疑惑了。下图展示了 Student 的构造函数的原型链。

知其所以然
发现了不解的地方,一个很好的办法就是通过实践来进行检验,多做几次实验测试,就能够发现规律。看下面这段代码。
function Person(){ //(Object|obj)
this.name="tjm";
}
function Student(){ s1
Person.call(this);
this.grade = 1;
}
Student.prototype = new Person(); // p1
var stu = new Student();
Student.prototype = new Person(); // p2
console.log(stu instanceof Student); // false
console.log(stu instanceof Person); // true
上面代码在 stu 实例化之后,再更改 Student 构造函数的原型实例,虽然原型实例还是一个 Person 对象,但是 stu instanceof Student 却为 false 了。下面通过原型对象来分析 instanceof 来判断的值。stu 在实例化时,内部 【prototype】 属性指向的是当时 Student 构造函数所指向的对象,那么 stu 原型对象是 p1 (Person 对象), 但是在 stu 对象实例化之后,Student 构造函数的原型更改为 p2 , 也是一个 Person 对象。虽然 p1,p2 都是 Person 的对象,但是他们却是不同的,拥有不同的内存地址,使用 == 操作符,结果是 false 。通过对上面代码进行分析,可以得出这样的结果:
obj instanceof Construcotr—> instanceof 操作符是判断 Constructor 构造函数的原型对象是否存在实例 obj 的原型链中,如果存在,那么返回true,否则返回 false。
根据上面总结再来分析一下代码,stu 实例的原型链中的对象为 p1,p0,Object, 而 Student 的原型对象为 p2 ,因此 stu instanceof Student 当然返回 false。 Student 的原型对象没有在 stu 实例的原型链中。明白了instanceof 操作符真的工作原理,下面我们很容更改 stu 原型链中的对象,使得 stu instancecof Student 返回 true。好在 es5 提供了 __proto__ 属性访问实例的原型。
function Person(){
this.name="tjm";
}
function Student(){
Person.call(this);
this.grade = 1;
}
var p1 = new Person();
Student.prototype = p1;
var stu = new Student();
var p2= new Person();
Student.prototype = p2;
stu.__proto__ = p2; //通过更改 stu 原型为 p2
console.log(stu instanceof Student); // true
console.log(stu instanceof Person); // true
通过 stu.__proto__ = p2; 语句,将 stu 的原型更改为与 Student 构造函数一样的原型对象 p2, 这下 stu instanceof Studetn 结果返回 true。
小结
instanceof 操作符作用是:在运行时,构造函数的原型对象是否出现在实例的原型链中,如果出现则返回 true,否则返回false。 切记,一定是运行时,而不是初始化时。
instanceof 是如何工作的的更多相关文章
- Javascript 封装问题
Javascript 封装问题 为什么会用这样一个题目呢,这是要说封装的什么问题,本文并不讲高深的封装理论,只是解决一个小问题. 问题来源 今天在百度知道上闲逛,遇到一个网友的问题,问题如下,问题的地 ...
- 深入理解JavaScript原型:prototype,__proto__和constructor
JavaScript语言的原型是前端开发者必须掌握的要点之一,但在使用原型时往往只关注了语法,其深层的原理并未理解透彻.本文结合笔者开发工作中遇到的问题详细讲解JavaScript原型的几个关键概念, ...
- javaScript 工作必知(六) delete in instanceof
in in 判断 左边 的字符串或者能转换成字符串的是否属于 右边 的属性. var data = { x: 1, y: 4 };//定义了直接对象 alert("x" in d ...
- 5.在MVC中使用泛型仓储模式和工作单元来进行增删查改
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...
- [翻译]Java HashMap工作原理
大部分Java开发者都在使用Map,特别是HashMap.HashMap是一种简单但强大的方式去存储和获取数据.但有多少开发者知道HashMap内部如何工作呢?几天前,我阅读了java.util.Ha ...
- [工作中的设计模式]解释器模式模式Interpreter
一.模式解析 解释器模式是类的行为模式.给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器.客户端可以使用这个解释器来解释这个语言中的句子. 以上是解释器模式的类图,事实上我 ...
- JSP工作原理
一.历史 JSP是Servlet的扩展,JSP没出现之前,就已经出现了Servlet技术.Servlet是利用了"输出流",动态的生成了HTML页面.包括 每一个HTML标签和所有 ...
- [zz]Java中的instanceof关键字
1.What is the 'instanceof' operator used for? stackoverflow的一个回答:http://stackoverflow.com/questions/ ...
- 每日学习心得:Js获取Checkboxlist所选值、instanceof 和typeof区别、为Array添加contains方法
2013-11-24 前言: 上周在工作中遇到了一些跟JS以及前台交互的问题,虽然算不上多么高深,但是在解决时也走了一些弯路,所以就总结一下. 1. JS获取checkboxList所选的值 这 ...
随机推荐
- express 最佳实践(二):中间件
express 最佳实践(二):中间件 第一篇 express 最佳实践(一):项目结构 express 中最重要的就是中间件了,可以说中间件组成了express,中间件就是 express 的核心. ...
- 如何写出面试官欣赏的Java单例
单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例. 今天我们不谈单例模式的用途,只说一说如果在面试的时候面试官让你敲一段代码 ...
- iOS开发实战-上架AppStore 通过内购和广告获得收益
写在前面 由于一些原因需要离职,准备重回大上海 忽然发现手头上也没什么独立App,那就随便写个放到AppStore上吧,凑个数吧.哈哈哈. 这个App是无聊找配色的时候看到的一套图 正好春节在家没什么 ...
- Java复习随笔
1.StringTokenizer str = new StringTokenizer("字符串"); str.countTokns(); //可得出字符串非连续的个数(可用于 ...
- 【整理】01. Fiddler 杂记
抓手机包步骤: Tools -- Fiddler Options -- Connections (默认)Fiddler listens on port:8888 (勾选)Allow remote co ...
- Redux源码分析之基本概念
Redux源码分析之基本概念 Redux源码分析之createStore Redux源码分析之bindActionCreators Redux源码分析之combineReducers Redux源码分 ...
- Hibernate三大类查询总结
Hibernate目前总共分为三大类查询:cretiria,hql,本地sql [以下篇章搜集于网络,感谢作者] 第一:关于cretiria的查询 具有一个直观的.可扩展的条件查询API是Hibern ...
- How to create a jump server in AWS VPC
本来是写的Word文档,给其他国家的同时看的,所以一开始就是英文写的,也没打算翻译成为中文了,顺便抱怨下,网上资料找了很久的资料都没有看到介绍怎么在单机环境下搭建RD Gateway的,写本文的目的是 ...
- F数圈圈
Description 幼儿园的小朋友对数字其实不是很感兴趣,他们更感兴趣的是形状,现在给你一个数字,小朋友都会数出其中一共有多少圆圈圈 Input 一个数字n长度不超过19位 Output 输出其中 ...
- 解决js中post提交数据并且跳转到指定页面的问题总结
今天在开发中过程中遇到了这个问题,js中利用JQuery中的 $.post("url", id, function(){}); 这个方法是数据提交正常,但是后台处理完成之后跳转无法 ...