【日常记录总结】如何理解原型与原型链

129 阅读3分钟

引言 整理自慕课网双越老师课程。

需要明白一些基础概念:

  • 如何class一个类
  • 如何继承一个类
  • 如何创建一个实例
  • 什么是原型
  • 明白了什么是原型,那原型链是否可以理解为多个原型形成的一条链路

原型

我们通过class一个类并且new这个类来理解下原型。

我们创建了Student的类,定义了一些参数和方法。

class Student {
    constructor(name, number) {
        this.name = name
        this.number = number
    }
    sayHi() {
        console.log(
            `姓名 ${this.name} ,学号 ${this.number}`
        )
    }
}

然后定义xialuo去实例化Student这个类,并且打印输出一些值。

const xialuo = new Student('夏洛', 100)
console.log(xialuo.name)
console.log(xialuo.number)
xialuo.sayHi()

可以看到我们成功打印出了夏洛以及100,并且可以成功调用Student里的方法。

再打印下xialuo看看到底是什么。

打印结果看到了xialuo有了Student的参数,并且还有一个__proto__(隐式原型),展开__proto__会发现其实就是我们创建的Student(理解为 prototype 显式原型),包括constructor,SayHi()和另外一个__proto__(这个暂且不讲,涉及到原型链。)

以上就是一个原型啦,总结一下:

  • 每个class(Function)都有显式原型 prototype
  • 每个实例对象都有隐式原型__proto__
  • 实例对象的隐式原型指向class的显示原型

原型链

理解了原型,那么原型链就很好理解了。举个例子:

创建一个父类People

// 父类
class People {
    constructor(name) {
        this.name = name
        this.age = 20
    }
    eat() {
        console.log(`${this.name} eat something`)
    }
}

再创建一个子类Student继承父类People,也就是extends的概念,简而言之能继承父类的方法和变量等。

传送门

// 子类
class Student extends People {
    constructor(name, number) {
        super(name)
        this.number = number
    }
    sayHi() {
        console.log(`姓名 ${this.name} 学号 ${this.number}`)
    }
}

如之前的原型一样,去实例化Student。

// 实例化
const xialuo = new Student('夏洛', 100)
console.log(xialuo.name)
console.log(xialuo.age)
console.log(xialuo.number)
xialuo.sayHi()
xialuo.eat()

打印一下看看,发现可以打印出父类的变量name age、子类的变量number,父类的方法eat(),子类的方法sayHi(),为啥能访问到呢,这就要靠原型链了。

再打印下实例xialuo看看是什么。

跟原型一样,xialuo有隐式原型__proto__,内容是子类Student的显式原型prototype,这也就是为什么xialuo可以打印出子类的方法和变量。

同时可以发现子类的Student也有隐式原型__proto__,内容是父类People的显式原型prototype,这也就是为什么xialuo可以打印出父类类的方法和变量。

截取老师视频中的关于原型链的简图。

以上就是一个原型啦,总结一下:

  • 访问一个对象的属性时,先在自身属性中查找,找到返回;
  • 如果没有,再沿着__proto__(隐式原型属性)这条链向上查找,找到返回;如果最终没有找到则返回undefined.
  • 因为原型链是沿着__proto__(隐式原型属性)查找,所以又叫隐式原型链.原型链的作用是查找对象属性(方法)的.
  • 从打印信息中不难看出,最终原型原型链都指向对象Object。

第一篇文章,希望能坚持记录下去。