这篇博客只是用来记录自己所学的知识。
说到继承,应该先提一下原型跟原型链。
那么什么是原型,我自己个人的理解是原型是一个对象,是一个当我们一行代码都不写就已经存在的那些对象,而且这些对象中包含的属性可以被其constructor属性指向的构造函数的所有实例共享。
比如我们在控制台输入Object.prototype,Array.prototype,Function.prototype等,回车的时候我们就能够看到结果里有很多东西。
如下图:
每个原型对象里面都会有一个constructor属性,它表明这个原型对象所在的构造函数是谁。
那么我们为什么需要原型对象呢?原因其实很简单,比如我们写了一个构造函数如下
function Person(name, age) {
this.name = name
this.age = age
this.sayName = function() {
console.log(this.name)
}
}
当我们每次new一个Person实例的时候,我们都必须给这个sayName方法分配内存空间,由于这个方法只是打印名字而已,我们当然也就觉得没必要这样子每次都分配内从空间,所以我们可以将这个sayName方法写到其原型对象中。
Person.prototype.sayName = function() {
console.log(this.name)
}
通过这样的方式,sayName这个方法就只需要分配一次内存空间即可,而且这个sayName方法可以被所有的Person实例共享,提高了方法的可复用性。
那么原型链又是什么呢。我们知道一个实例被new出来的时候,其实经历了这样的一个过程。
第一步: 创建一个空对象
第二步: 将这个对象链接到其构造函数的原型对象上,也就是这个实例会有一个__proto__指针,指向构造函数的原型对象
第三步: 将这个对象绑定到this上
第四步: 返回这个对象
我们主要看第二步,由于所有原型对象都是Object的实例对象,我们看一下是不是真的是这样
我们看到打印结果的确是这样子的,正因为原型对象是Object 的实例对象,因此原型对象也都会被链接到Object的原型对象上,所以原型对象也就都会有一个__proto__指针。
其实我们可以自己去尝试一下,就会发现实例与实例之间,都是通过__proto__这样的一个属性连接起来的,被连接起来的对象叫做原型对象,连接起来的所有原型对象就叫做原型链。
以上的这些就是我对原型跟原型链的理解。
如有描述不妥的地方请指出,小弟会非常感谢。