重新认识js的原型链

232 阅读2分钟

重新认识__proto__,prototype和constructor

  • __proto__:是任何对象在创建时都会有的属性,指向了产生当前对象的构造函数的原型对象,所谓的原型链就是由__proto__连接而成的链。它已不被推荐使用,现在更推荐使用Object.getPrototypeOf、Releft.getPrototypeOf和Object.setPrototypeOf、Reflect.setProtottypeOf

    注意:__proto__的写法,proto前后有两个英文输入的_(下划线)。

  • prototype:只有构造函数才会有的属性,指向的是当前构造函数的原型对象。

  • constructor:只有原型对象才有的属性,默认指回prototype属性所在的构造函数(指向函数本身)。

    JS中不管什么类型的对象,都一定有构造函数,它包括构造函数本身 接下来我们看一段代码:

          function Supermarket() {  
          };
          Supermarket.prototype.product = "糖果";
    
          function Shop() { };
          Shop.prototype = new Supermarket();
          Shop.prototype.drink = "可乐";
    
          var person1 = new Shop();
          var person2 = new Shop();
         
          console.log(person1.drink);//可乐
          console.log(person1.product);//糖果
          console.log(person2.drink);//可乐
          console.log(person2.product);//糖果
    

    在这段代码中我们可以假设一个情景: 1、我们有一个叫做Supermarket的空构造函数,然后将product属性直接加到了Supermarket的prototype属性中;

    2、还有一个叫做Shop的空构造函数,然后将Supermarket构造函数加到Shop的prototype属性中,再将dirnk属性加到Shop的prototype属性中;

    3、通过调用Shop这个构造函数来创建person1和person2新对象,且新对象还具有相同的属性和方法。 要求我们输出person1.dirink、person1.product、person2.dirink、person2.product,结果如下: 我们的person(也就是person1和person2)要找drink和product这俩个属性,首先实例会先在自身上找有没有这个属性,结果没有这俩个属性,就会通过__proto__找实例的原型对象,person的原型对象是Shop,我们发现Shop中有drink属性,但是却没有product属性,我们继续找Shop的原型,Shop的原型是Supermarket,我们发现Supermaket有属性product,我们要找的属性也全部找完了,就可以返回结果了。

    找原型的时候我们是从底向上一步一步往上找的

我们也可以打印一下实例的__proto__和原型的prototype是否相等,如果相等,我们找的就没有问题

        console.log(person1.__proto__ === Shop.prototype)
        console.log(person1.__proto__.__proto__ === Supermarket.prototype)

更多关于js原型的知识点,建议看红宝书第六章。