Javascript深入__proto__和prototype的区别和联系

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

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自己看去

原文地址:https://www.cnblogs.com/ghyes/p/9153342.html

时间: 2024-07-30 13:42:15

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

javaScript中__proto__与prototype的区别与联系

[转]javaScript中__proto__与prototype的区别与联系 2014-5-4阅读490 评论0 最近在学习javascript的原型,发现了__proto__与prototype,学问很大,于是研究了一下. 首先解释一下什么是原型? 原型是一个对象,其他对象可以通过它实现属性继承. 对象又是什么呢? 在javascript中,一个对象就是任何无序键值对的集合,如果它不是一个主数据类型(undefined,null,boolean,number,array,string),那它

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

prototype: Function有内置的prototype属性,而Object没有.其实这一点与上一点有着很大的关系,正是因为有了把Function当做构造函数的功能,我们才需要prototype属性.只要记住一点,prototype只有Function才有. _Proto_: 一个与 prototype 遥相呼应的属性是 __proto__(请注意有 proto 两边各有两个下划线),一个实例的 __proto__ 属性指向创建该实例的类的 prototype 对象. 区别: __pro

__proto__与prototype的区别与联系

最近在学习javascript的原型,发现了__proto__与prototype,学问很大,于是研究了一下. 首先解释一下什么是原型? 原型是一个对象,其他对象可以通过它实现属性继承. 对象又是什么呢? 在javascript中,一个对象就是任何无序键值对的集合,如果它不是一个主数据类型(undefined,null,boolean,number,array,string),那它就是一个对象. 那么如何查看一个对象的原型是啥呢?又如何给一个对象设置原型呢? 标准对象原型访问器Object.ge

js中__proto__和prototype的区别和联系

作者:苏墨橘来源:知乎 备注:本篇文章比较清楚的解释了__proto__属性.prototype.instanceof,秉持一贯风格,好文收藏,贴在这里供大家学习. __proto__(隐式原型)与prototype(显式原型) 1.是什么 显式原型 explicit prototype property: 每一个函数在创建之后都会拥有一个名为prototype的属性,这个属性指向函数的原型对象.Note:通过Function.prototype.bind方法构造出来的函数是个例外,它没有pro

再说javascript 的__proto__ 和prototype 属性

过了一段时间,没写 原生的 javascript 的了,感觉天天在用框架写代码,框架写代码完全限定死了你所需要思考的东西,只是在处理一些业务逻辑,真正的代码 都感觉不会写了. 突然发现,框架用的不熟悉,原生的代码也忘得差不多了.感觉很难受,人生不能这样子度过! 重新翻开<javascript 高级程序设计>, 回归到本原.工作上用框架写代码没错,业余时间的话就要自己多写一点原生的代码,或者说研究.模仿.直到自己设计一个 框架出来. js 中的类, 对象, 类的静态变量,类的继承 .functi

JavaScript中__proto__与prototype的关系

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

JavaScript中__proto__与prototype的关系(转)

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

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

_proto__(隐式原型)与prototype(显式原型) 1.是什么 显式原型 explicit prototype property: 每一个函数在创建之后都会拥有一个名为prototype的属性,这个属性指向函数的原型对象.Note:通过Function.prototype.bind方法构造出来的函数是个例外,它没有prototype属性.(感谢 @陈禹鲁 同学的答案让我知道这一点) NOTE Function objects created using Function.prototy

javascript中__proto__与prototype的关系及原型继承的原理

1.__proto__与prototype的关系 所有对象的__proto__都指向其构造器的prototype var a = {"test":'mico',"age":"18"}; var b = function(){}; var c = new Date(); var d = /^[\d]$/; alert(a.__proto__ == Object.prototype); //true alert(b.__proto__ == Func