JavaScript学习笔记 .8——原型机制(3)原型链

100 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

原型链

JavaScript访问属性的机制

我们回顾一下上节的知识点:每个实例对象都有一个另一个实例对象作为原型,一环套一环。

继续摆出上节的例子:

function A(){
    this.member1='abc';
}
var a = new A();
var b = Object.create(a);

写一个原型链

b:{
   b自己的成员
   ...
   __proto__:a{
      a自己的成员
      ...
      __proto__:A.prototype{
         constructor : A
         A.prototype自己的成员
         ...
         __proto__:Object.prototype{
            constructor : Object
            和一些其他的奇奇怪怪的东西
            ...
            __proto__:null
      }
    }
  }
}

在这个原型链下,原型链上游的成员是可以让原型链下游的对象直接调用的。例如:

当你访问b的一个属性,就先查找b有没有这个属性;有的话返回值,没有的话去b的原型找,即在a中找;以此类推,直到把所有的__proto__都找完了还没有,那就返回undefined

现在通过重写上面的代码段来创建一些成员:

function A(){
  this.member1="In A's code";
  this.__proto__.constructor.prototype.member2="In A's prototype";
};
var a=new A();
var b=Object.create(a);
a.member3="Created by a itself";
b.member4="Created by b itself";

在往下看之前,可以自己思考一下,对于创建的成员member1member2member3member4,对象ab可以访问哪些成员,访问时他们属于哪个原型。

答案揭晓:

此时b同时含有member1member2member3member4,其中member4是自己创建的,member3b的原型a创建的,member2b的原型的原型A.prototype创建的,member1a创建的。

可能有些人会感到疑惑:A是一个对象,那member1是不是属于A的呢?使用控制台打印得到:

A.member1:
undefined

看来this.member1="In A's code"并不会为A对象创建成员。那为什么a中会存在member1呢?这就涉及到new运算符的机制了:

我自己对于new的理解:

  • 先构建了一个空实例对象;
  • 然后将对象的引用赋值给后面函数的this,使得函数可以使用this指针创建成员;
  • 以后面函数的prototype属性作为实例的原型,使得可以继承其方法。

这就是JS构建实例的基本原理!在下节我将给大家探讨修改成员时发生的事,大家不要错过~