注意:前方高能预警,请认真仔细看完,阅读完后自己再次画下原型图,相信你一定会有更深刻的认识。(推荐炒鸡好用的画流程图的软件ProcessOn)

构造函数:function Foo ( ) { };

实例对象:let f1=new Foo;

let o1=new Foo;

每个函数都有 prototype 属性,除了 Function.prototype.bind(),该属性指向原型

每个对象都有 __proto__ 属性指向了创建该对象的构造函数的原型。其实这个属性指向了 [[prototype]],但是 [[prototype]] 是内部属性,我们并不能访问到,所以使用 _proto_ 来访问。

对象可以通过 __proto__ 来寻找不属于该对象的属性,__proto__ 将对象连接起来组成了原型链。

下面我们来解释上图的原型图的含义:

概念:

1、构造函数:用来初始化新创建的对象的函数是构造函数。在例子中,Foo()函数是构造函数。

2、实例对象:通过构造函数的new操作创建的对象是实例对象。可以用一个构造函数,构造多个实例对象。

function Foo(){};
var f1 = new Foo;
var f2 = new Foo;
console.log(f1 === f2);//false复制代码

3、原型对象及prototype:构造函数有一个prototype属性,指向实例对象的原型对象。通过同一个构造函数实例化的多个对象具有相同的原型对象。经常使用原型对象来实现继承。

function Foo(){};
Foo.prototype.a = 1;
var f1 = new Foo;
var f2 = new Foo;console.log(Foo.prototype.a);//1
console.log(f1.a);//1
console.log(f2.a);//1复制代码

4、constructor:原型对象有一个constructor属性,指向该原型对象对应的构造函数。由于实例对象可以继承原型对象的属性,所以实例对象也拥有constructor属性,同样指向原型对象对应的构造函数。

console.log(Foo.prototype.constructor === Foo);//true
console.log(f1.constructor === Foo);//true复制代码

5、_proto_:实例对象有一个proto属性,指向该实例对象对应的原型对象。

console.log(f1.__proto__ === Foo.prototype);//true复制代码

概念介绍完了,现在对图示的关系进行详细说明

【第一部分: Foo】

1、实例对象f1是通过构造函数Foo()的new操作创建的。构造函数Foo()的原型对象是Foo.prototype;实例对象f1通过__proto__属性也指向原型对象Foo.prototype。

console.log(f1.__proto === Foo.prototype);//true
复制代码

2、实例对象f1本身并没有constructor属性,但它可以继承原型对象Foo.prototype的constructor属性

console.log(Foo.prototype.constructor === Foo);//true
console.log(f1.constructor === Foo);//true
console.log(f1.hasOwnProperty('constructor'));//false复制代码

  下图是实例对象f1的控制台效果

【第二部分: Object】

1、Foo.prototype是f1的原型对象,同时它也是实例对象。实际上,任何对象都可以看做是通过Object()构造函数的new操作实例化的对象 所以,Foo.prototype作为实例对象,它的构造函数是Object(),原型对象是Object.prototype。相应地,构造函数Object()的prototype属 性指向原型对象Object.prototype;实例对象Foo.prototype的proto属性同样指向原型对象Object.prototype。

console.log(Foo.prototype.__proto__ === Object.prototype);//true
复制代码

2、实例对象Foo.prototype本身具有constructor属性,所以它会覆盖继承自原型对象Object.prototype的constructor属性。

console.log(Foo.prototype.constructor === Foo);//true
console.log(Object.prototype.constructor === Object);//true
console.log(Foo.prototype.hasOwnProperty('constructor'));//true复制代码

  下图是实例对象Foo.prototype的控制台效果

3、如果Object.prototype作为实例对象的话,其原型对象是什么,结果是null。我以为,这可能也是typeof null的结果是'object'的原因之一吧。

console.log(Object.prototype.__proto__ === null);//true
复制代码

【第三部分: Function】

1、前面已经介绍过,函数也是对象,只不过是具有特殊功能的对象而已。任何函数都可以看做是通过Function()构造函数的new操作实例化的结果。如果把函数Foo当成实例对象的话,其构造函数是Function(),其原型对象是Function.prototype;类似地,函数Object的构造函数也是Function(),其原型对象是Function.prototype。

console.log(Foo.__proto__ === Function.prototype);//true
console.log(Object.__proto__ === Function.prototype);//true复制代码

2、原型对象Function.prototype的constructor属性指向构造函数Function();实例对象Object和Foo本身没有constructor属性,需要继承原型对象Function.prototype的constructor属性。

console.log(Function.prototype.constructor === Function);//true
console.log(Foo.constructor === Function);//true
console.log(Foo.hasOwnProperty('constructor'));//false
console.log(Object.constructor === Function);//true
console.log(Object.hasOwnProperty('constructor'));//false
复制代码

3、所有的函数都可以看成是构造函数Function()的new操作的实例化对象。那么,Function可以看成是调用其自身的new操作的实例化的结果。所以,如果Function作为实例对象,其构造函数是Function,其原型对象是Function.prototype。

console.log(Function.__proto__ === Function.prototype);//true
console.log(Function.prototype.constructor === Function);//true
console.log(Function.prototype === Function.prototype);//true复制代码

4、如果Function.prototype作为实例对象的话,其原型对象是什么呢?和前面一样,所有的对象都可以看成是Object()构造函数的new操作的实例化结果。所以,Function.prototype的原型对象是Object.prototype,其原型函数是Object()。

console.log(Function.prototype.__proto__ === Object.prototype);//true
复制代码

总结:

【1】函数(Function也是函数)是new Function的结果,所以函数可以作为实例对象,其构造函数是Function(),原型对象是Function.prototype。

【2】对象(函数也是对象)是new Object的结果,所以对象可以作为实例对象,其构造函数是Object(),原型对象是Object.prototype

【3】Object.prototype的原型对象是null。

一张图理解JS的原型(prototype、_proto_、constructor的三角关系)相关推荐

  1. JS 一张图理解prototype、proto和constructor的关系

    转载于原文地址:https://www.cnblogs.com/xiaohuochai/p/5721552.html(感谢大神的总结) 前面的话 javascript里的关系又多又乱.作用域链是一种单 ...

  2. [转]一张图理解prototype、proto和constructor的三角关系

    本文转自:http://www.cnblogs.com/xiaohuochai/p/5721552.html 前面的话 javascript里的关系又多又乱.作用域链是一种单向的链式关系,还算简单清晰 ...

  3. 一张图理解RACSignal的Subscription过程

    通过下面一张图理解RACSignal的调用过程: 创建signale RACSignal通过子类[RACDynamicSignal createSignal:]方法获得Signal,并将disSubs ...

  4. 一图胜千言,8 张图理解 Java

    一图胜千言,8 张图理解 Java 一图胜千言,下面图解均来自Program Creek 网站的Java教程,目前它们拥有最多的票选.如果图解没有阐明问题,那么你可以借助它的标题来一窥究竟. 1.字符 ...

  5. 一张图理解AOP关键概念

    一张图理解AOP关键概念 Aspect(切面) Joint Point(连接点) Advice(通知) Pointcut(切入点) Weaving(织入) 这里以跟踪方法调用为例,Calculate为 ...

  6. 一周极客热文:8张图理解Java

    图:equals()方法.hashCode()方法的区别 HashCode被设计用来提高性能.equals()方法与hashCode()方法的区别在于: 如果两个对象相等(equal),那么他们一定有 ...

  7. 从babel实现es6类的继承来深入理解js的原型及继承

    先聊个5毛钱的背景吧 自从有了babel这一个利器之后,es6现在已经被广泛的使用.JavaScript 类实质上是 JavaScript 现有的基于原型的继承的语法糖.类语法不会为JavaScrip ...

  8. 怎么理解js的原型链继承?

    前言 了解java等面向对象语言的童鞋应该知道.面向对象的三大特性就是:封装,继承,多态. 今天,我们就来聊一聊继承.但是,注意,我们现在说的是js的继承. 在js的es6语法出来之前,我们想实现js ...

  9. 用一张图理解SVM的脉络

    本文及其它机器学习.深度学习算法的全面系统讲解可以阅读<机器学习与应用>,清华大学出版社,雷明著,由SIGAI公众号作者倾力打造,自2019年1月出版以来已重印3次. 书的购买链接 书的勘 ...

最新文章

  1. mysql 分支 XtraDB Percona MariaDB 简介
  2. linux 内核 虚拟文件系统VFS 路径查找 path_lookup
  3. 使用QT制作桌面小工具(一)
  4. 查询反模式 - GroupBy、HAVING的理解
  5. hibernate 表关系映射详解之继承关系
  6. JAVA程序设计----关于字符串的一些基本问题处理
  7. Linux内核Socket参数调优
  8. 具有代理设置的Spring Cloud AWS
  9. 什么是引力波?它是怎么被发现的?
  10. 新手赛(2) 第五题 因素和问题
  11. ip subnet-zero 和ip classless 的用法
  12. ffmpeg 编码如何做带宽控制输出
  13. 1.2低级线程处理API
  14. 交互式多模型_体系化教学资源上新——小学数学交互式教学工具
  15. 全国python一级考试_关于全国青少年软件编程(Python)等级考试试卷(一级)测试卷情况网络调研...
  16. oracle中subject是什么意思,subject是什么意思_subject的翻译_音标_读音_用法_例句_爱词霸在线词典...
  17. windows 7中的windows键相关的快捷键
  18. Ajax Control Toolkit 控件介绍
  19. 双11,立减¥3554!戴尔官网撩客服砍价带走高性能电脑,速来!
  20. Sprintf函数用法

热门文章

  1. Python bytearray/bytes/string区别 - Python零基础入门教程
  2. thinkphp仿素材火教程_国外都用古风效果图获奖了,为什么你连素材都没有?
  3. java创建临时文件夹_java创建临时文件
  4. 订阅号 笔记记录开发 php,微信订阅号开发笔记(五)
  5. mysql存儲過程_Mysql存儲過程 | 學步園
  6. map multimapc++_黑马C++视频笔记《STL之map/multimap》
  7. android 通话结束广播,在Android中以编程方式结束通话
  8. ROS开发时的服务器启动命令
  9. 蓝桥杯 历届试题 带分数
  10. AC_Dream 1216 G - Beautiful People