有一个一个装逼的同事,写了一段代码

function a(){}
a.__proto__.__proto__.__proto__

然后问我,下面这个玩意a.__proto__.__proto__.__proto__是啥,然后我一脸懵逼,prototype还知道一点,这个__proto__,还来三个,是个什么鬼。于是我一直不能放下这个问题,虽然我很懒,很不喜欢费脑子,但是这个坎还是过不去,最近两天研究了大半天,就有了这篇文章。
我先说出答案, 上面的值为 null。我还很负责的告诉你,下面的_a.__proto__.__proto__.__proto__也是null

function a(){}
var _a = new a();
_a.__proto__.__proto__.__proto__

先来一张非常经典的图,真的是非常经典,你看懂他,你就懂了整个世界,然后整个世界就等着你去拯救整个世界。
)

正文之前,__proto__和prototype

都谁有的问题

typeof === object的有__proto__ , null和undefined都没有
typeof === function的有__proto__和prototype

__proto__ 是什么
__proto__ 一般情况指向的是该对象的构造函数的prototype,一般情况,因为还有很二般的情况。
先来看个简单的例子, 下面的输出是true

function a(){}
var _a = new a()
console.log(_a.__proto__ === a.prototype)

那我问_a.__proto__.__proto__为什么呢,你会这么推导么,
依据上面_a.__proto__ === a.prototype,那么_a.__proto__.__proto__就等同a.prototype.__proto__ , 那么我们就再推到等于 a.prototype.constructor.prototype,然后你去一比,结果是false。

_a.__proto__.__proto__  === a.prototype.constructor.prototype
// false

几条规则
这个先不纠结, 我们先看看上图,我们先得知道或者记住这几个规则

  1. Object.prototype.__proto__ === null
    不要纠结,铁律
  2. Object.__proto__ === Function.prototype
    Object,Number, Error等等这些函数都是Function创建的,下面就说明
    这些的constructor就是Function,这里比较有意思的就是 Function.constructor也是Function。
    那就有Object.__proto__ === Function.prototype === Function.__proto__

    Object.constructor.prototype  === Function.prototype
    // true
    Function.constructor === Function
    // true
  3. Function.prototype.__proto__ === Object.prototype
    这个就是这样的设计,

    Function.prototype.constructor === Object
    // false

    进入正题

    有这几个基本东西,我们就可以来推导了。

先看下面的代码,
js 我们来推到 aaa.__proto__.__proto__.__proto__

function aaa(){}
var _aaa = new aaa()
  1. aaa.__proto__
    aaa构造函数是Function
    aaa.constructor === Function
    aaa.__proto__ === Function.prototype

  2. aaa.__proto__.__proto__
    aaa.__proto__.__proto__ === Function.prototype.__proto__
    依据 Function.prototype.__proto__ === Object.prototype
    aaa.__proto__.__proto__ === Function.prototype.__proto__ === Object.prototype

  3. aaa.__proto__.__proto__.__proto__
    aaa.__proto__.__proto__.__proto__ === Object.prototype.__proto__
    依据 Object.prototype.__proto__ === null
    aaa.__proto__.__proto__.__proto__ === null

还是上面代码,我们接着推导_aaa.__proto__.__proto__.__proto__

  1. _aaa.__proto__
    _aaa的构造函数是 aaa
    _aaa.constructor === aaa
    _aaa.__proto__ === _aaa.constructor.prototype
    _aaa.__proto__ === aaa.prototype

  2. _aaa.__proto__.__proto__
    _aaa.__proto__.__proto__ === aaa.prototype.__proto__
    参考图,Foo.prototype.__proto__ === Object.prototype
    _aaa.__proto__.__proto__ === aaa.prototype.__proto__ === Object.protype

  3. _aaa.__proto__.__proto__.__proto__
    _aaa.__proto__.__proto__.__proto__ === Object.protype.__proto__
    依据 Object.prototype.__proto__ === null
    _aaa.__proto__.__proto__ === null

正文延伸, 加上继承关系

我们再来看看,带继承关系的

function aaa(){}
function bbb(){}
bbb.prototype = new aaa()
var _bbb = new bbb();

bbb.__proto__.__proto__.__proto__ === null
这个没啥好说,
关键来看看 bbb.prototype.__proto__.__proto__.__proto__

  1. bbb.prototype.__proto__
    bbb.prototype.__proto__ === bbb.prototype.constructor.prototype
    bbb.prototype的原型是 aaa的实例, bbb原型的构造函数就是aaa,所以
    bbb.prototype.__proto__ === aaa.prototype

  2. bbb.prototype.__proto__.__proto__
    bbb.prototype.__proto__.__proto__ === aaa.prototype.__proto__
    参考图,Foo.prototype.__proto__ === Object.prototype
    bbb.prototype.__proto__.__proto__ === Object.prototype

  3. bbb.prototype.__proto__.__proto__
    bbb.prototype.__proto__.__proto__ .__proto__=== Object.prototype.__proto__ === null

再来看看_bbb.__proto__.__proto__.__proto__ .__proto__

  1. _bbb.__proto__
    _bbb.__proto__ === bbb.prototype
  2. _bbb.proto.proto
    _bbb.__proto__.__proto__ === bbb.prototype._proto__ === bbb.prototype.constructor.prototype === aaa.prototype
  3. _bbb.proto.proto.proto
    _bbb.__proto__.__proto__.__proto__ === aaa.prototype.__proto__
    参考图Foo.prototype.__proto__ === Object.prototype
    _bbb.__proto__.__proto__.__proto__ === aaa.prototype.__proto__ === Object.prototype
  4. _bbb.__proto__.__proto__.__proto__.__proto__
    _bbb.__proto__.__proto__.__proto__.__proto__ === Object.prototype.__proto__ === null

正文 再加量

看看如下代码

function aaa(){}
var _aaa = new aaa() function bbb(){}
bbb.prototype = new aaa(); var _bbb = new bbb(); function ccc(){}
ccc.prototype = new bbb()
var _ccc = new ccc()

我们再来分析_ccc的prototype__proto__,你们会说,你有完没完
,那我就不分析了,我来推断:

推断:

  1. 任何自定义的function本身,三次__proto__必然是null,也就是往上找三代
    包括Function,Object, Error等等
    Fucntion.proto 看图,依据
    Object.__proto__ === Function.prototype === Function.__proto__
    我们来推导Function.__proto__.__proto__ .__proto__
    第一步:Function.__proto__ === Function.prototype
    第二步:Function.__proto__.__proto__ === Function.prototype.__proto__ === Object.protetype
    第三步:Function.__proto__.__proto__ .__proto__ === Object.protetype.__proto__ === null
    都是Function构造出来的
    我们来测试一下ccc

    ccc.__proto__.__proto__.__proto__ === null // true
  2. 继承关系的function fn,假设继承次数为n,
    _fn = new fn();
    那么 _fn.__protot__[3 + n] === null
    _ccc应该是3+2就是5次

    _ccc.__proto__.__proto__.__proto__.__proto__.__proto__ === null // true
  3. 继承关系的function fn,假设继承次数为n
    推到 fn.prototype.__proto__[3+n-1]
    ccc应该是 4次__proto__

    ccc.prototype.__proto__.__proto__.__proto__.__proto__ === null // true

    当然上面关联的关系,就自己慢慢看吧

正文之外, class

下面的代码也是遵守规则,至于为什么,问自己喽。

class aaa {}
class bbb extends aaa{}
class ccc extends bbb{};
var _ccc = new ccc()

关于Number,Boolen, String,Function, Date, Array, RegExp等的__proto__prototype.proto`

  1. __proto__
    因为这些都是Function创建出来的函数,__proto__在函数上时就是表示构造函数的prototype,所以
    .__proto__ === .constrcutor.prototype === Function.prototype
  2. .prototype.__proto__ 这些老骨头不遵循 __proto__ 为构造函数的prototype
    在上面提到过了,Function.prototype.__proto__ === Object.prototype
    类推,这些内置的老骨头的 .prototype.__proto__ === Object.prototype

## 总结
总结, 特别需要记忆的:

  1. Object.prototype.__proto__ === null
  2. Function.prototype.__proto__ === Object.prototype
    内置Number,Boolen, String,Function, Date, Array, RegExp等一样
  3. Object.__proto__ === Function.prototype === Function.__proto__
    联系2,这些东西都是Function创建出来的
  4. Math, JSON的__ptoto__是 Object.prototype
    typeof 可以看出来这两个是object,而不是Function
  5. function a(){} 这样创建出来,没有继承关系的函数
    a.prototype.__proto__ === Object.prototype
  6. 有继承关系的function看上面的推断
  7. 对象字面量和new Object() 比如, var a ={}, b = new Object(), c = [];
    a.__proto__ === a.constructor.prototype === Object.protype
    a.__proto__.__proto__ === Object.protype.__proto__ === null
  8. 基本数据类型string,number,boolean,比如 var a = '', b=10, c= false,
    b.__proto__ === b.constructor.prototype === Number.prototype
    b.__proto__.__proto__ === Number.prototype.__proto__ === Object.prototype
    b.__proto__.__proto__.__proto__ === Object.prototype.__proto__ === null
  9. null和undefined没有__proto__

最终

    1. 看图
    2. 浏览器输入 xx.__proto__ 或者xx.prototype自己看去

Javascript深入__proto__和prototype的区别和联系的更多相关文章

  1. 【JavaScript】__proto__和prototype的区别和联系【整理】

    var person={name:'ninja'}; person.prototype.sayName=function(){ return this.name; } Chrome运行结果: 提示找不 ...

  2. 谈谈__proto__和prototype的区别

    我想javascript中的原型链一直想很多初学javascript的同学感到非常的困惑,今天看了一些文章,结合自己的理解,把原型链这个东西从新来整理一下,如有不对之处,望大家帮忙指出. 首先,我们应 ...

  3. js中__proto__和prototype的区别和关系? 这样好理解多了

    原型的概念 真正理解什么是原型是学习原型理论的关键.很多人在此产生了混淆,没有真正理解,自然后续疑惑更多. 首先,我们明确原型是一个对象,其次,最重要的是, Every function has a ...

  4. JavaScript中__proto__与prototype的关系

    一.所有构造器/函数的__proto__都指向Function.prototype,它是一个空函数(Empty function) 1 2 3 4 5 6 7 8 9 Number.__proto__ ...

  5. js中__proto__和prototype的区别和关系?

    _proto__(隐式原型)与prototype(显式原型)1.是什么 显式原型 explicit prototype property: 每一个函数在创建之后都会拥有一个名为prototype的属性 ...

  6. 再说javascript 的__proto__ 和prototype 属性

    过了一段时间,没写 原生的 javascript 的了,感觉天天在用框架写代码,框架写代码完全限定死了你所需要思考的东西,只是在处理一些业务逻辑,真正的代码 都感觉不会写了. 突然发现,框架用的不熟悉 ...

  7. JavaScript的__proto__、prototype和继承

    JavaScript也是可以“继承”的! 各位看官或是好奇,或是一知半解.什么是prototype,__proto__,constructor.哪种继承方式好.今天就在这交流交流. 什么是protot ...

  8. JavaScript中__proto__与prototype的关系(转)

    一.所有构造器/函数的__proto__都指向Function.prototype,它是一个空函数(Empty function) 1 2 3 4 5 6 7 8 9 Number.__proto__ ...

  9. 深入__proto__和prototype的区别和联系

    前话 有一个一个装逼的同事,写了一段代码 function a(){} a.__proto__.__proto__.__proto__ 然后问我,下面这个玩意a.__proto__.__proto__ ...

随机推荐

  1. JOB SERVER 负载均衡

    JOB SERVER 负载均衡 一.体系结构 1.job server group job server group 是由一个或者多个job server 组成的,做为一个整体对外提供服务,在内部实现 ...

  2. Oracle 自定义实用函数

    一.ctod 字符转为date, create or replace function ctod(str in varchar2) return date as begin return to_dat ...

  3. iOS:手势与矩形、点运算相关(18-01-24更)

    1.矩形.点运算 1.获取当前的View在Window的frame 2.包含判断 3.获取点击在响应者 touchesBegan 的位置 4.UIScrollView.UITableView 实时 位 ...

  4. #leetcode刷题之路22-括号生成

    给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n = 3,生成结果为:[ "((()))", "(()())&q ...

  5. html-表单标签

    表单标签 * 可以提交数据到**网站上的服务器,这个过程可以使用表单标签实现 * <form></form>:定义一个表单的范围 - 属性 ** action:提交到地址,默认 ...

  6. 如何提交代码到git仓库

    首先连接远程仓库 git remote add origin 仓库地址 然后拉取分支 git pull origin master 随后可查看本地增删改的文件 git status 增加本地的更改 g ...

  7. 学习html的第一天

    HTML 第一章: webde 运行环境: 1. 什么是HTML HTML 是用来描述网页的一种语言. HTML 指的是超文本标记语言:HyperText Markup Languge 超文本 就是网 ...

  8. Selenium_python自动化第一个测试案例(代码基本规范)

    发生背景: 最近开始整理Selenium+python自动化测试项目中相关问题,偶然间翻起自己当时学习自动化时候写的脚本,发现我已经快认不出来写的什么鬼流水账了,所以今天特别整理下自动化开发Selen ...

  9. 【树形DP】MZOJ_1063_士兵守卫

    本题也是这三天来在下写的几篇树形DP之一,但是不知道为什么洛谷上面老是unknown error,...直接去了UVa,说我编译错误...我在想是不是头文件的原因,于是被逼无奈,交了一道c89的代码. ...

  10. 学习Emmet

    学习Emmet 在进行Web开发时,就免不了需要编写html文件,如何快速(偷懒^-^)的进行编写html,是个大问题,上网找了一下,发现了一个好东西 ,视频教程可以看下小马技术Emmet爆速开发, ...