原型-原型链-继承 前端

1. 适用范围:

  1. 可以给这个prototype(原型对象)定义新方法和新属性,这是实际应用中用的最多的

梗概:

  • 在类和实例之间会存在一个实例原型(prototype)
    • 用来存储实例的方法
    • 不储存类属性
      • 因为不同实例的属性是相互独立的
    • 这个实例原型通常使用父类的名字进行命名

1. 图片梗概:

2. 说明:

1. 存储原型对象的变量的多种名字

  • 在edge的开发者工具中, __proto__显示为[[prototype]]

2. 实例化机制

  1. 当从一个类中实例化对象时, 实例化对象会拿到这个类所继承得到的属性, 但方法不能被实例直接拿到
  2. 这个类中的方法(独有的方法, 不是被继承的), 会被保存在这个类的一个特殊属性中: prototype
    1. 该特殊属性被称为显性原型
    2. 构造方法也会被保存在prototype
  3. 然后用这个类A去实例化对象a的时候, 实例对象也会有一个特殊的属性: __proto__(在chrome开发工具中又写作__proto__), 这个属性和类A的prototype属性都指向同一个原型
    1. 这个特殊的属性被称为隐性原型

3. 原型链

  1. 如果这个类还是继承自其他的类的话, 如class Son extends Father, 则Son.prototype中也会保存有一个隐形原型: __proto__, 指向Father.prototype
  2. 这样实例对象根据类的继承关系, 就得到了一条原型链, 即__proto__中还有__proto__
    1. 其中每一层__proto__对应了其中一个类中的方法集合

4. 通过实例自动查找原型链

  1. 当通过实例化对象去调用方法的时候, 会从原型链中找方法
    1. 这样就实现了类的继承原理

5. 在nodejs中的兼容性

  • 在nodejs中不能通过实例获取原型对象

实例说明:

1. 实例一:

class GrandF{
  constructor(){
    this.Grandname='grandFa'
  }
  grandFaSay(){
  }
}
class Father extends GrandF{
  Fathername='fuck';
  FatherSay(){}
}
class Son extends Father{
  Sonname='son';
  SonSay(){}
}
let son = new Son()

在Edge控制台中查看son实例:

2. 实例二:

child::多种方式添加类方法的区别

实例之一

child::

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    say() {
        console.log('名字' + this.name + '今年' + this.age);
    }
    run = () => {
        console.log(this.name + '可以run');
    }
    eat() {
        console.log('可以吃');
    }
}
class CloneMan extends Person {
    constructor(name, age) {
        super(name, age);
    }
  
    say = () => {
        console.log('我叫' + this.name + '今年' + this.age);
    }
    run() {
        console.log(this.name + '真的可以run');
    }
    eat = () => {
        console.log('还可以吃');
    }
}
const tom = new CloneMan('tom', '20')
tom.say() //我叫tom , 今年20  CloneMan的say
tom.run() //tom可以run  Person的run
tom.eat() //还可以吃  CloneMan的eat
指向原始笔记的链接