时间回到两个月前,简单地理了理原型链、prototype以及__proto__之间的乱七八糟的关系,同时也简单了解了下typeof和instanceof两个运算符,但是,anyway,试试以下两题:

console.log(Function instanceof Function);
console.log(String instanceof String);

  如果无法得出准确答案,跟着楼主一起温故而知新吧。

温故

  我们经常用typeof运算符来判断一个变量的类型,也确实挺好用,能判断出number、boolean、string,但是对于object的判断能力一般,比如Array和null的判断结果都是object,而且对于new的一些对象,比如new String(),new Number()等的结果都是object,这样下来就有个问题,无法更细致地判断对象实例,这时就需要instanceof出马了。顾名思义,instanceof是判断一个对象是否为某一构造函数实例的运算符,这样下来,对于new出来的变量,到底是number、string还是别的什么玩意,就有了进一步的判断认识了。看起来很简单,其实不然,上面的两题就是小试牛刀了,先放着,再来回顾下原型链。

  JavaScript中一切皆为对象,所有对象都有个__proto__属性值(即原型),可能某些坑爹浏览器下不支持,暂且不管,某对象的该属性的取值是该对象的构造函数的prototype值,作用就是对于某一个类型的对象,不用重复定义某种方法,譬如说对于对象[1,2,3],显然这是个数组对象,它具有pop、push等方法,但是并不是说它本身就具有这些方法,而是它的构造函数Array函数所具有,而该对象的__proto__取值就是Array函数的prototype值,so如果本身并不具有pop方法,就会从它的__proto__中寻找,即所谓的原型链;而该条链的末端就是Object,因为一切对象都是由Object构造而成,而Object.prototype.__proto__规定指向null。

  文字的描述永远是苍白无力的,举个简单的例子:

var fun = function(){
  this.a = 1;
};

fun.prototype.b = 2;
var obj = new fun();
obj.a;
obj.b; 

  网上盗的例子和图,仔细看就会发现说的很清楚。

知新

  接下来看看instanceof运算符。

  instanceof的常规用法是判断a是否是b类型:

console.log(true instanceof Boolean); // false
console.log(new Number(1) instanceof Number); // true

  instanceof还能判断父类型:

function Father() {}
function Child() {}
Child.prototype = new Father();
var a = new Child();
console.log(a instanceof Child);  // true
console.log(a instanceof Father); // true

  Child构造函数继承自Father,实例a是Child构造的无疑,但是为何也是Father的实例呢?其实instanceof运算符的内核可以简单地用以下代码描述:

function check(a, b) {
  while(a.__proto__) {
    if(a.__proto__ === b.prototype)
      return true;
    a = a.__proto__;
  }
  return false;
}

function Foo() {}
console.log(Object instanceof Object === check(Object, Object)); // true
console.log(Function instanceof Function === check(Function, Function)); // true
console.log(Number instanceof Number === check(Number, Number)); // true
console.log(String instanceof String === check(String, String)); // true
console.log(Function instanceof Object === check(Function, Object)); // true
console.log(Foo instanceof Function === check(Foo, Function)); // true
console.log(Foo instanceof Foo === check(Foo, Foo)); // true

  简单地说,a如果是b的实例,那么a肯定能使用b的prototype中定义的方法和属性,那么用代码表示就是a的原型链中有b.prototype取值相同的对象,于是顺着a的原型链一层层找就行了。

  另外值得注意的是,String Number Boolean 以及Function等都是函数,而函数则是统一由Function构造而来的,so它们和任何单纯的函数一样,能用Function上的原型属性:

Function.prototype.a = 10;
console.log(String.a);  

  最后来简单讲讲最开始的两道题吧。

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

  先介绍到这里,如有不对之处还望指出~

JavaScript原型链和instanceof运算符的暧昧关系的更多相关文章

  1. 资料--JavaScript原型链

    JavaScript原型链 原文出处:https://www.cnblogs.com/chengzp/p/prototype.html 目录 创建对象有几种方法 原型.构造函数.实例.原型链 inst ...

  2. JavaScript学习总结(十七)——Javascript原型链的原理

    一.JavaScript原型链 ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法.其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.在JavaScript中, ...

  3. javascript原型链中 this 的指向

    为了弄清楚Javascript原型链中的this指向问题,我写了个代码来测试: var d = { d: 40 }; var a = { x: 10, calculate: function (z) ...

  4. 明白JavaScript原型链和JavaScrip继承

    原型链是JavaScript的基础性内容之一.其本质是JavaScript内部的设计逻辑. 首先看一组代码: <script type="text/javascript"&g ...

  5. Javascript 原型链资料收集

    Javascript 原型链资料收集 先收集,后理解. 理解JavaScript的原型链和继承 https://blog.oyanglul.us/javascript/understand-proto ...

  6. JavaScript原型链:prototype与__proto__

    title: 'JavaScript原型链:prototype与__proto__' toc: false date: 2018-09-04 11:16:54 主要看了这一篇,讲解的很清晰,最主要的一 ...

  7. JavaScript原型链及其污染

    JavaScript原型链及其污染 一.什么是原型链? 1.JavaScript中,我们如果要define一个类,需要以define"构造函数"的方式来define: functi ...

  8. javascript中原型链与instanceof 原理

    instanceof:用来判断实例是否是属于某个对象,这个判断依据是什么呢? 首先,了解一下javascript中的原型继承的基础知识: javascript中的对象都有一个__proto__属性,这 ...

  9. 详谈JavaScript原型链

    目录 创建对象有几种方法 原型.构造函数.实例.原型链 instanceof的原理 new运算符 创建对象的方法 在了解原型链之前,首先先了解一下创建对象的几种方式,介绍以下三种. 代码: <s ...

随机推荐

  1. 每日Scrum--No.9

    Yesterday:测试软件 Today:写阶段性的总结 Problem: (1)晚上我们的团队进行了收尾工作:第一阶段的任务基本完成,软件主要实现了校园景点照片以及对应的介绍,查询最短路径,查询涉及 ...

  2. android JSON解析之JSONObject与GSON

    1.写在前面 JSON数据是android网络开发中常见的数据格式,JSON最常见的传输方法是使用HTTP协议,关于android开发中HTTP协议的使用方法可参考我的另一篇随笔android网络编程 ...

  3. JavaScript Patterns 3.3 Patterns for Enforcing new

    When your constructor has something like  this.member and you invoke the constructor without  new,  ...

  4. HttpClient使用方法(包括POST文件)

    最近在做跨系统的数据交互业务,从.Net的系统提交数据到Java的系统. 简单的表单Get.POST都没问题,但是有个功能是要提交普通文本和文件,试了好多都有问题,最后用HttpClient小折腾了一 ...

  5. 机器学习五 -- 机器学习的“Hello World”,感知机

    机器学习五 -- 机器学习的“Hello World”,感知机 感知机是二类分类的线性分类模型,是神经网络和支持向量机的基础.其输入为实例的特征向量,输出为实例的类别,取+1和-1二值之一,即二类分类 ...

  6. OFFICE2013实现选中单元格所在行、列高亮显示

    在你要实现此功能的工作表标签右击,在弹出的菜单中选择编辑代码,然后输入下面代码保存即可! 如没有出现效果,则可能是禁用了宏的关系.所以要在安全选项中启用宏选项. Private Sub Workshe ...

  7. java自带命令工具

    jstat,这个工具很强大,可以监测Java虚拟机GC多方面的状态,具体参数含义参见此链接: ./jstat -gc 84012 1000 3 S0C    S1C    S0U    S1U     ...

  8. 1644 免费馅饼 题解(c++)(S.B.S.)

    1644 免费馅饼(巴蜀oj上的编号) 题面:          SERKOI最新推出了一种叫做“免费馅饼”的游戏.         游戏在一个舞台上进行.舞台的宽度为W格,天幕的高度为H格,游戏者占 ...

  9. 《TCP/IP详解 卷一》读书笔记-----UDP&IP 分片

    1.进程每产生一个UDP数据报就由一个IP数据报进行发送,而在TCP中,一个IP数据报并不与每个TCP报文段一一对应 2.UDP的端口号和TCP的端口号是相互独立的,对那些众所周知的端口号TCP和UD ...

  10. Linux (二) vi

    1  步骤 1)  vi  test.txt 进入一般模式 2)   i    进入编辑模式,输入内容 3)  Esc 回到一般模式 4)  :wq 存储后退出 2  编辑模式 [i] 光标处插入, ...