如何理解原型链中的prototype和__proto__?

JavaScript是动态的,本身不提供一个class实现。在ES2015/ES6中引入了class关键字,但那只是语法糖,JavaScript仍然是基于原型的。

一、什么是原型链?

  谈到继承时,JavaScript只有一种结构:对象
MDN文档上是这样说的:每个实例对象(object)都有一个私有属性(称之为__proto__)指向它的构造函数的原型对象(prototype)。该原型对象也有一个自己的原型对象(__proto__),层层向上直到一个对象的原型对象为null。根据定义,null没有原型,并作为这个原型链中的最后一个环节。

二、换种方式理解原型链?

  之前在慕课网上,听过一个讲师举了一个很有趣的例子来介绍什么是prototype(当时偷偷的用手机截了图o):
  简单粗暴一点,我们把prototype理解成一个“备胎”,手艺还是祖传的。有一个姑娘不会修电脑,自己也不想学,就去找prototype说你学学吧,学好了帮我把修电脑这活儿做好,
prototype学会了修电脑之后,这个姑娘电脑有问题就会去找prototype,其他的姑娘再想修电脑时候,prototype这修电脑的技术也能直接拿出来用。
后来,又有姑娘请prototype帮忙诊个脉,prototype没有地方学,就往祖上一辈辈的问去,后来了解到他爷爷会诊脉,后来再有人找他诊脉,prototype就把病人带着找它爷爷。
再后来,又有一个姑娘让prototype给她造个机器人,prototype问遍了祖上,没人会这门技术,只能告诉这姑娘null了。

三、为什么需要原型和原型链?

  看一个小例子:

    function Person(name,age){
        this.name = name;
        this.age  = age;
        this.eat  = function(){
            console.log(age + "岁的" + name + "在吃饭");
        }
    }
    let p1 = new Person("YQ",27);
    let p2 = new Person("YQ",27);
    console.log(p1.eat === p2.eat);  //false

  我们发现上面的例子,对于同一个函数,我们可以通过new生成出来的实例,p1和p2的eat是不同的。我们想个办法,建立一个类似于共享库的对象,这样就可以在需要的时候,调用一个类似共享库的对象,让实例能够沿着某个“线索”去找到自己的归处。
这个“线索”就是我们的原型链 prototype。

    function Person(name){
        this.name = name;
    }
    //通过构造函数的Person的prototype属性找到Person的原型对象
    Person.prototype.eat = function(){
        console.log("吃饭");
    }
    let p1 = new Person("YQ",27);
    let p2 = new Person("XX",27)

    console.log(p1.eat === p2.eat);//true

 通过分享的形式,这两个实例对象指向相同的位置了,也就是我们想要创建的共享库的对象。

四、prototype是什么玩意儿呢?

知乎上有一篇文章(https://zhuanlan.zhihu.com/p/22989691) 写的很好,总结一下就是:
1、JavaScript本源是空的,即:null,这个就是JavaScript的“始祖”;

2、null通过__proto__产生了NO1,即:NO1.__proto__ == null;

3、NO1根据自己的原型prototype创建了对象Object,即:Object.prototype == NO1;

4、NO1.__proto__ == null,我们把prototype叫做原型,好比Object的原型是神,同时__proto__叫做原型链,有了这个__proto__,Object、NO1、JS之间才有联系,此时,Object.prototype.__proto__ == null

5、有几条公式:

              Object.__proto__ === Function.prototype;
              Function.prototype.__proto__ === Object.prototype;
              Object.prototype.__proto__ === null;
posted @ 2019-12-31 16:14  JudeYQ  阅读(337)  评论(0编辑  收藏  举报