• JS 原型和原型链


    1. 了解原型和原型链

    1.1 原型

    原型: prototype 又称显示原型

    1、原型是一个普通对象
    2、只有构造函数才具备该属性
    3、公有属性可操作

    1.2 原型链

    原型链:__proto__

    1、只有对象(普通对象、函数对象)具备
    2、私有的对象属性,不可操作

    有了上面的概念之后,我们再来探讨一下什么是原型和原型链。

    2. 原型

    我们知道在JS中每次创建一个函数,该函数就会自动带有一个prototype属性,该属性指向函数的原型对象。

    2.1 prototype

    // 生成一个构造函数
    function Person() {
      this.name = 'wyc'
    }
    
    // 在原型上添加属性
    Person.prototype.age = 19
    
    // 实例化对象
    let person = new Person()
    
    console.log(person);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    上述例子中,函数的prototype指向了一个对象,而这个对象正是调用构造函数时创建的实例的原型,也就是person1和person2的原型。

    让我们用一张图来展示 构造函数 与 原型对象 之间的关系:
    在这里插入图片描述

    2.2 __proto__ 隐式原型

    这是js对象中(null和undefined除外)都会存在的属性,这个属性会指向该对象的原型(注意:__proto__因为浏览器兼容性问题,不一定都可以获取到,应当使用Object.getPrototypeOf函数作为获取对象原型的标准API)。

    隐式原型只有对象(普通对象、函数对象)才具备,并且隐式原型是一个私有的对象属性,不可操作。

    // 生成一个构造函数
    function Person() {
      this.name = 'wyc'
    }
    
    // 在原型上添加属性
    Person.prototype.age = 19
    
    // 实例化对象
    let person = new Person()
    
    console.log(Person.prototype);
    console.log(person.__proto__);
    console.log(person.__proto__ === Person.prototype);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

    通过这个打印结果我们会发现,看着上面这张图,让我们来总结下:

    • 构造函数(Person)通过prototype属性指向实例的原型。
    • person是基于原型Person.prototype创建出的实例,并且可以通过__proto__属性指向其原型。
    • Person.prototype和person.__proto__都指向实例的原型。

    看着上面的描述来看这张图片
    在这里插入图片描述

    3. 原型链

    在JavaScript 中,每个对象通过__proto__属性指向它的原型对象,这个原型对象又有自己的原型,直到某个对象的原型为 null 为止,这种一级一级的链结构就称为原型链。

    class Person {  // 生成父类
      constructor(name) {
        this.name = name;
      }
    
      drink() {
        console.log('大家都爱喝可乐');
      }
    }
    
    class Teacher extends Person {  // 生成子类  继承 父类的属性和方法
      constructor(name, age) {
        super(name)
        this.age = age;
      }
    
      teach() {
        console.log('wyc 喜欢 前端工作');
      }
    }
    
    let my = new Teacher('wyc', 19)
    console.log(my);
    my.teach();
    my.drink()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    看下面这副图,通过打印构造函数中的teach方法,能够打印出结果
    在打印父类中的drink方法,也是可以打印出结果
    在这里插入图片描述

    通过下面这副图来详细的了解下

    1. 大家可以看到首先能够展示的是我们构造函数中的数据
    2. 调用teach方法时找不到,那么会通过自己的隐式原型__proto__访问到原型对象,在原型对象中寻找。(红色部分)
    3. 在调用drink方法时找不到,那么先通过__proto__找到自己的隐式原型,可以看出隐式原型中也是没有drink方法的,那么在通过__proto__向上寻找,找到后打印。
    4. 如果一直找到Object.prototype对象上,还没有打印,那么就说明,整个原型链对象上都没有此方法,那么就打印为null
      在这里插入图片描述

    我们也可以通过 哈默 这张图理解下:
    在这里插入图片描述

  • 相关阅读:
    Basic Facilities of a Virtio Device (一)
    通过数(判断一个数是否在集合M中)
    51单片机中断操作详解(03)
    数据分析实战应用案例精讲-【概念篇】用户画像(最终篇)(附实战案例)
    数据分析-Pandas两种分组箱线图比较
    【Spring Cloud】认识微服务架构,拆分简单的 Demo 实现服务的远程调用
    黑猫带你学Makefile第13篇:Makefile编译问题合集
    程序员需知的8个视频教程网站,建议收藏
    精心整理的Java学习顺序流程和学习方法
    设计高信度和效度的问卷:关键要点与技巧
  • 原文地址:https://blog.csdn.net/wu_2004/article/details/132916017