原型和原型链
面试的时候常常会问到什么是原型?什么是原型链?原型对象是什么?原型链是如何实现的?本文以简单的方式清晰的解释这些疑问,面试的时候可以应答自如。
原型是什么?
那什么是原型呢?你可以这样理解:每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。
class Person {
}
Person.prototype.firstName = 'John';
const person = new Person()
console.log(person.firstName)
/*
* 为什么这里的person会存在say方法?
* 因为person的创建其实是关联了Person对象,然后继承了他的方法
*
*/
__proto__是什么?
这是每一个JavaScript对象(除了 null )都具有的一个属性,叫__proto__,这个属性会指向该对象的原型
prototype是什么?
每个构造函数都具有prototype属性,这个属性指向一个对象,称之为原型对象, 当我们通过构造函数创建实例的时候,这些实例都会共享prototype上面的方法
原型对象是什么?
比如 Person.prototype 就是一个原型对象(顾名思义,原型指向的对象)
图解&&代码解释
class Father {
}
class Person extends Father {
}
Person.prototype.firstName = 'John';
const person = new Person()
const father = new Father()
console.log(person.__proto__ === Person.prototype)// true
console.log(Person.prototype.constructor === Person)// ture
console.log(Person.prototype.__proto__ === Father.prototype)// true
原型链
由图可以看出,通过__proto__和prototpe属性,在父和子之间形成了一个链式结构,这就是原型链条,但是这样一直连接下去肯定需要一个尽头,那么这个尽头就是什么?尽头就是Object的原型,也就是Object.prototype,所有普通对象的原型链最终都指向 Object.prototype,这是 JavaScript 中几乎所有对象的基原型(根原型),因为 Object.prototype.__proto__ 是 null,这标志着原型链的结束。
原型链有什么作用?
-
原型链是Javascript实现继承的重要方式:因为通过原型链,子类对象可以访问父类(或原型对象)上的属性和方法,实现继承。子类可以通过其原型链访问并使用父类定义的属性和方法
-
很好的实现属性,方法共享:当我们访问一个属性的时候,当前原型对象上没有的时候就会顺着原型链往上找,如果都没有就会返回null,也可以很好的解释为什么
Function上可以有toString()方法
也可以通过原型链实现继承
class Father {
say () {
console.log('hello')
}
}
class Person {
}
Person.prototype.firstName = 'John';
const person = new Person()
const father = new Father()
Person.prototype.__proto__ = Father.prototype
person.say()