搞懂 JS 中的原型链

什么是原型链?:

  • 说这个之前,让我们先理一理构造函数,原型和实例的关系,我们知道,每个构造函数都有一个原型对象(也就是prototype这个属性), 原型对象都包含一个指向构造函数的指针(也就是constructor属性), 而实例都包含一个指向原型对象的内部指针 ( 也就是 _ proto _ 或者 叫它 [ [ prototype ] ] )

  • 那么假如我们让原型对象等于另一个类型的实例,结果会怎样呢?显然,此时的原型对象将包含一个指向另一个原型对象的指针

  • 假如另一个原型链又是另一个类型的实例,那么上述关系依旧成立,如此层层递进,就构成了实例与原型的链条。这就是所谓原型链的基本概念。

说了这么多,还是上代码实用点


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Documenttitle>
head>
<body>

    <script>
        function Father() {
          this.name = "老王";
        }
        Father.prototype.sayName = function () {
          console.log(this.name);
        }
        Father.prototype.sayHello = function () {
          console.log("我是你爸爸");
        }
        function Son() {
          this.name = "小王";
        }
        Son.prototype = new Father();
        Son.prototype.sayHello = function () {
          console.log("我是你儿子");
        }
        var son = new Son();
        var father = new Father();
        console.log(son);
        console.log(father);
        son.sayName();     // 小王
        father.sayName();  // 老王
        son.sayHello();    // 我是你儿子
        father.sayHello(); // 我是你爸爸
    script>
body>
html>

这里有两个构造函数 Father 和 Son
我们让Son的原型对象 ( prototype属性 ) 等于通过Father构造函数构造出来的实例,这样就实现了Son 对 Father 的继承,实现的本质是重写原型对象,用一个新类型的实例取而代之,这样的话,存在于 Father 构造函数原型上的方法,Son的实例对象都可以访问了。

打开chrome控制台,一目了然。
搞懂 JS 中的原型链_第1张图片

Son实例对象son有一个 _ proto _ 指针指向Son.prototype, 而Son.prototype 又等于 Father的实例,Father的实例 又有一个 _ proto _ 指针指向 Father.prototype
当我们 通过 son.sayName() 试图去访问Father.prototype 上的方法时,会经历以下三个搜索步骤

  1. 搜索实例,也就是实例对象son,发现没有,接着找
  2. 搜索 Son.prototype ,瞅了瞅发现又没有
  3. 最后再去搜索 Father.prototype 发现找到了

    这也就是原型链的搜索机制
    所以当我们调用 sayHello 方法时,发现Son.prototype上有这个方法,自己有当然就用自己的,所以打印的是 “我是你儿子”

你可能感兴趣的:(javascript)