知其然

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 是如何工作的的更多相关文章

  1. Javascript 封装问题

    Javascript 封装问题 为什么会用这样一个题目呢,这是要说封装的什么问题,本文并不讲高深的封装理论,只是解决一个小问题. 问题来源 今天在百度知道上闲逛,遇到一个网友的问题,问题如下,问题的地 ...

  2. 深入理解JavaScript原型:prototype,__proto__和constructor

    JavaScript语言的原型是前端开发者必须掌握的要点之一,但在使用原型时往往只关注了语法,其深层的原理并未理解透彻.本文结合笔者开发工作中遇到的问题详细讲解JavaScript原型的几个关键概念, ...

  3. javaScript 工作必知(六) delete in instanceof

    in in 判断  左边 的字符串或者能转换成字符串的是否属于 右边 的属性. var data = { x: 1, y: 4 };//定义了直接对象 alert("x" in d ...

  4. 5.在MVC中使用泛型仓储模式和工作单元来进行增删查改

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...

  5. [翻译]Java HashMap工作原理

    大部分Java开发者都在使用Map,特别是HashMap.HashMap是一种简单但强大的方式去存储和获取数据.但有多少开发者知道HashMap内部如何工作呢?几天前,我阅读了java.util.Ha ...

  6. [工作中的设计模式]解释器模式模式Interpreter

    一.模式解析 解释器模式是类的行为模式.给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器.客户端可以使用这个解释器来解释这个语言中的句子. 以上是解释器模式的类图,事实上我 ...

  7. JSP工作原理

    一.历史 JSP是Servlet的扩展,JSP没出现之前,就已经出现了Servlet技术.Servlet是利用了"输出流",动态的生成了HTML页面.包括 每一个HTML标签和所有 ...

  8. [zz]Java中的instanceof关键字

    1.What is the 'instanceof' operator used for? stackoverflow的一个回答:http://stackoverflow.com/questions/ ...

  9. 每日学习心得:Js获取Checkboxlist所选值、instanceof 和typeof区别、为Array添加contains方法

    2013-11-24 前言: 上周在工作中遇到了一些跟JS以及前台交互的问题,虽然算不上多么高深,但是在解决时也走了一些弯路,所以就总结一下. 1.    JS获取checkboxList所选的值 这 ...

随机推荐

  1. java 线程之concurrent中的常用工具 CyclicBarrier

    一.CyclicBarrier CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序 ...

  2. Linux安装搜狗输入法教程

    最近开始学习linux 在安装输入法中遇到的一些问题,最终成功安装,也得益于网络上的前辈写的文章,现在将全部安装步骤以及遇到的一些问题总结如下:   基本上分三步走 1,添加fcitx的键盘输入法系统 ...

  3. 蓝桥杯比赛javaB组练习《四平方和》

    四平方和 四平方和定理,又称为拉格朗日定理:每个正整数都可以表示为至多4个正整数的平方和.如果把0包括进去,就正好可以表示为4个数的平方和. 比如:5 = 0^2 + 0^2 + 1^2 + 2^27 ...

  4. Java中基本数据类型和包装类

    参考:深入剖析Java中的装箱和拆箱; Java中基本数据类型和包装类互转中 缓冲机制的使用; java学习笔记:装箱和拆箱,包装器和缓冲池 Java 各 类型数据在内存中分配情况详解 一 java内 ...

  5. 又见angular----步一步做一个angular4小项目

    这两天看了看angular4的文档,发现他和angular1.X的差别真的是太大了,官方给出的那个管理英雄的Demo是一个非常好的入门项目,这里给出一个管理个人计划的小项目,从头至尾一步一步讲解如何去 ...

  6. js验证15位或18位身份证

    本篇文章是本人在网上搜集了一些验证,然后又个人进行一定修改的关于身份证的验证,欢迎修改指正..... function IdCardValidateRule(idCard) { var tip;    ...

  7. angular或者js如何确定选中ul中的哪几个li

    刚来新公司接到新的需求做一个知识库页面 红色的是单选    蓝色的是多选     这些都是需要传递到后台的 开始不知道如何解决  下班后在家想到一个很巧妙的办法  不多说上代码 箭头所指就是在li里写 ...

  8. 【有意思的BUG】未名

    这个帖子描述定位一个BUG的思路. 开始了. 用浏览器访问某一个网址http://111.aaa.com/ ,如果发现提示异常,那么接下来该如何定位BUG呢? 用相同的浏览器去访问不同域(不是aaa. ...

  9. Cmd Markdown 学习

    [TOC] # Cmd Markdown 学习 Markdown 简明语法 1. 斜体和粗体 使用 * 和 ** 表示斜体和粗体. 2. 分级标题 在使用 = 表示一级标题,使用 - 表示二级标题.# ...

  10. JS进阶 ] 分析JS中的异步操作

    写在前面 JS因为是单线程的,所以在执行事务的时候,往往会因为某个事务的延迟,而导致服务器假死,这时候异步编程就显的格外重要,但是异步编程一般理解为回调函数callback,典型的就是node,回调函 ...