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所选的值 这 ...
随机推荐
- Haproxy的配置
1,下载Haproxy 下载Haproxy 1.6 2,安装haproxy uname -r cd /usr/local/src/haproxy-1.6.9/ make TARGET=linux31 ...
- 【javascript】数组的操作
一.常用操作 toString():把数组转换成一个字符串 toLocaleString():把数组转换成一个字符串 join():把数组转换成一个用符号连接的字符串 shift():将数组头部 ...
- Orchard 学习
https://github.com/OrchardCMS/Orchard 源码下载 http://www.orchardch.com/ 中文介绍网站
- 封装自己的Ajax框架
Ajax技术就是利用javascript和xml实现异步交互的功能. 首先先来介绍一下Ajax相关知识点 一.Ajax对象的创建 1.创建Ajax对象的方式 a.第一种方式是针对IE浏览器 b.第二种 ...
- Ztree _ 横向显示子节点、点击文字勾选、去除指定元素input的勾选状态
前些天项目需要树结构表现数据,需求ztree就能满足所以直接使用ztree只是踩了些小坑... 1.ztree子节点横向显示(下图): 效果说明:第三级子节点按需求横向显示其他竖向显示,每行最多显示5 ...
- Spring-Framework 源码阅读之@Autowired和AutowiredAnnotationBeanPostProcessor
今天接下去讲我们的内容,上次的解析了AnnotationBeanUtils这个类的运用和源码.今天主要关注的是Autowired和 AutowiredAnnotationBeanPostProcess ...
- 使用VS Code开发.Net Core 2.0 MVC Web应用程序教程之二
好了,废话也不多说,咱们直接来看看这款MVC的造型——你可能会大吼:“这……这特么的都是些什么鬼?” 靠,告诉你吧,我也不知道这都是些什么鬼,反正以前我是没有见过这样的MVC.咦,老纸的config文 ...
- JS的事件多次触发,只执行最后一次
有时候我们在JS编程的过程中经常遇到一个问题就是事件频繁高速被触发,利用计时器来控制频率又会丢弃掉有用的事件,我们只是想让程序执行最后一次的事件,那么就可以用如下方法解决问题 //写在事件外边,防止被 ...
- css 定位功能position
Static 定位 HTML元素的默认值,即没有定位,元素出现在正常的流中.静态定位的元素不会受到top, bottom, left, right影响. 相对定位Relative相对定位元素的定位是相 ...
- 纯JavaScript实现异步Ajax的基本原理
Ajax实际就是XMLHttpRequest对象和DOM.(X)HTML和CSS的简称,用于概括异步加载页面内容的技术. Ajax实例 HTML代码如下,包含一个h5标题和一个按钮: JS代码如下 ...