先来看一张图,这张图可以说是围绕以下代码完整的描述了各对象之间的关系。接下来我们来看看如何一步步画出这张图。

function Foo(){};
var foo = new Foo();

首先,明确几点概念(现在不懂没关系),后面会不断提到:

过程1:只要创建一个函数Foo,就会为该函数创建一个prototype属性,这个属性指向函数的原型对象

过程2:原型对象会默认去取得constructor属性,指向构造函数。

过程3:当调用构造函数创建一个新实例foo后,该实例的内部将包含一个指针__proto__,指向构造函数的原型对象。

以上两点,出现了3种对象:构造函数、构造函数的原型、构造函数创建的实例;出现了3种属性:constructor、prototype、__proto__。接下来,我们就围绕这3个对象和3个属性展开讨论。

原型对象

1)先来看看第一行代码发生了什么:

function Foo(){};
console.log(Foo.prototype.constructor === Foo);//true

第一行代码定义了一个函数,此时就发生了过程1和过程2,如图:

(这里的Foo的原型对象一般表示为Foo.prototype,但为了更清晰理解,我们就称之为Foo的原型对象)

2)再来看看第二行代码

function Foo(){};
var foo = new Foo();
console.log(foo.__proto__ === Foo.prototype);//true

第二行代码创建了一个实例,发生了过程3,如图:

仔细观察,可以发现实例foo与构造函数之间是没有直接联系的,所有关系都是通过Foo的原型对象连接起来的。(这一点一定要明确)

3)foo继承constructor属性

function Foo(){};
var foo = new Foo();
console.log(foo.constructor === Foo);//true
console.log(foo.hasOwnProperty("constructor"));//false

实例对象foo与Foo之间没有直接联系,但foo继承了Foo的原型对象的constructor的属性,有了间接的联系。通过hasOwnProperty函数(判断对象是否拥有某个属性,不检查原型链)可以看出,实例对象foo本身没有constructor属性。

小结:到这里,博客最开始的两行代码的所有过程就结束了。不过这只是露在外面的冰山一角,我们来看看冰山下面有什么。

默认原型

我们知道,所有引用对象都默认继承了Object,所有函数的默认原型都是Object的实例。

1)同上,Object与其原型对象之间也存在如下关系

2)既然函数的默认原型都是Object的实例,那么类似以上创建foo实例时的过程,自然有了以下关系:

注意一点,此时Foo的原型对象有自己的constructor属性,自然就不用继承Object原型对象的了,所以仍然指向Foo,而不是Object。

3)Object的原型对象的原型

Object的原型对象已经是最根部了,所以它没有__proto__属性。

console.log(Object.prototype.__proto__);

Function

我们知道,函数也是对象,任何函数都可以看作是由构造函数Function实例化的对象。

1)同上,Function与其原型对象之间也存在如下关系

2)如果将Foo函数看作实例对象的话,其构造函数就是Function(),原型对象自然就是Function的原型对象;同样Object函数看作实例对象的话,其构造函数就是Function(),原型对象自然也是Function的原型对象。

3)Function的__proto__指针

Function自身可以看作通过构造函数Function实例化的对象,所以Function的__proto__指针指向Function的原型对象

4)Function的原型对象的__proto__指针

如果Function的原型对象看作实例对象的话,如前所述所有对象都可看作是Object的实例化对象,所以Function的原型对象的__proto__指向Object的原型对象。

总结:

到这里,创建一个实例对象foo时内部的联系就都说清楚了。观察图可以发现,只有一个入口(foo),一个出口(null),所以每一个对象都是同一个起源。

原型链中的prototype、__proto__和constructor的关系的更多相关文章

  1. JS原型链中的prototype与_proto_的个人理解与详细总结

    一直认为原型链太过复杂,尤其看过某图后被绕晕了一整子,今天清理硬盘空间(渣电脑),偶然又看到这图,勾起了点回忆,于是索性复习一下原型链相关的内容,表达能力欠缺逻辑混乱别见怪(为了防止新人__(此处指我 ...

  2. 关于JS中原型链中的prototype与_proto_的个人理解与详细总结

    一直认为原型链太过复杂,尤其看过某图后被绕晕了一整子,今天清理硬盘空间(渣电脑),偶然又看到这图,勾起了点回忆,于是索性复习一下原型链相关的内容,表达能力欠缺逻辑混乱别见怪(为了防止新人__(此处指我 ...

  3. JS中原型链中的prototype与_proto_的个人理解与详细总结(**************************************************************)

    一直认为原型链太过复杂,尤其看过某图后被绕晕了一整子,今天清理硬盘空间(渣电脑),偶然又看到这图,勾起了点回忆,于是索性复习一下原型链相关的内容,表达能力欠缺逻辑混乱别见怪(为了防止新人__(此处指我 ...

  4. JS中原型链中的prototype与_proto_的个人理解与详细总结

    1.对象的内部属性[[prototype]]和属性__proto__:每个对象都具有一个名为__proto__的属性: 2.函数的属性prototype:每个构造函数(构造函数标准为大写开头,如Fun ...

  5. 原型链继承中的prototype、__proto__和constructor的关系

    前不久写了有关原型链中prototype.__proto__和constructor的关系的理解,这篇文章说说在原型链继承中的prototype.__proto__和constructor的关系. 通 ...

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

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

  7. javascript原型链中 this 的指向

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

  8. js delete删除对象属性,delete删除不了变量及原型链中的变量

    js delete删除对象属性,delete删除不了变量及原型链中的变量 一.delete删除对象属性 function fun(){ this.name = 'gg'; } var obj = ne ...

  9. 原型及原型链,以及prototype和__proto__属性(笔记便于以后复习)

    首先,js的数据结构有 原始类型(5种):Boolean.Number.String.Null.Underfined, 然后是引用类型:Array.Date.Error.RegExp.Function ...

随机推荐

  1. 数学规划求解器lp_solve超详细教程

    前言 最近小编学了运筹学中的单纯形法.于是,很快便按奈不住跳动的心.这不得不让我拿起纸和笔思考着,一个至关重要的问题:如何用单纯形法装一个完备的13? 恰巧,在我坐在图书馆陷入沉思的时候,一位漂亮的小 ...

  2. PHP下的浮点运算不准的解决办法

    首先看一段代码: 首先看一段代码: <?php $a = 0.1; $b = 0.7; var_dump(($a + $b) == 0.8); 打印出来的值居然为 boolean false P ...

  3. docker阿里云镜像加速器使用

    加速器使用:加快镜像下载速度 访问www.aliyun.com: 登录之后点击”控制台“,选择“产品与服务“: 选择“容器镜像服务“: 设定密码后选择“镜像加速器”:  这里会有一个加速器地址:  在 ...

  4. flask _bootstrap中使用flash

    在模板中获取flash闪现的那段代码要和内容块放在同一级别上.不然网页上是看不到闪现的内容的. 比如在基模板里定义一个content block ,里面一个是get_flashed_messages代 ...

  5. fiddler安装和使用

    App抓包原理 客户端向服务器发起HTTPS请求 抓包工具拦截客户端的请求,伪装成客户端向服务器进行请求 服务器向客户端(实际上是抓包工具)返回服务器的CA证书 抓包工具拦截服务器的响应,获取服务器证 ...

  6. 查看哪个用户、IP、什么时间登陆过服务器

    2019-01-07 utmpdump /var/log/wtmp 或者 who /var/log/wtmp

  7. Android中通过xml改变背景及文字颜色

    原创文章,转载请注明出处,谢谢! 本篇主要介绍Android开发中,通过XML资源文件来设置控件在不同状态下的背景及文字颜色.关于xml改变背景及文字颜色的原理,大家可以去看一下郭霖大神的源码分析文章 ...

  8. (转)LVS安装使用详解

    原文:https://www.cnblogs.com/MacoLee/p/5856858.html 简介 LVS是Linux Virtual Server的简称,也就是Linux虚拟服务器, 是一个由 ...

  9. Java 并发编程——Callable+Future+FutureTask

    Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...

  10. java service wrapper将java程序包装成系统服务(一)

    一. 概述 使用java语言开发应用程序,在windows平台下,一般存在3种应用形式: 1. web应用.web应用多数打成war包在web容器(如tomcat,jetty等)中运行. 2. 桌面应 ...