在JavaScript中,每个对象都有一个原型对象,它可以通过__proto__属性来访问。如果一个属性在对象本身上不存在,JavaScript引擎会沿着原型链向上查找,直到找到该属性或者到达原型链的顶端为止。
原型链可以通过以下方式来实现:每个对象都有一个内部属性 [[Prototype]],它指向该对象的原型对象。当我们访问一个对象的属性时,如果该对象本身不存在该属性,则JavaScript引擎会沿着原型链查找该属性。如果在原型链上找到了该属性,则返回该属性的值;否则返回undefined。
例如,假设我们有一个对象People:
class People {
constructor(name) {
this.name=name
}
eat() {
console.log(`My name is ${this.name}`)
}
}
我们可以通过以下方式来创建一个新对象Student,并将其原型设置为People:
class Student extends People {
constructor(name,number) {
super(name)
this.number = number
}
sayHi () {
console.log(`Hi~ ${this.name}, ${this.number}`)
}
}
现在,Student对象的原型是People,因此它继承了People对象的函数eat。如果我们尝试访问People对象的eat函数,JavaScript引擎会沿着原型链向上查找,最终找到People对象的eat函数并调用。
接下来,我们将Student实例化,创建一个新的对象xialuo,并将其原型设置为Student。
const xialuo = new Student('xialuo', 100)
xialuo.eat()
我们可以看到xialuo对象可以使用People对象的name属性。主要原因是JavaScript引擎会沿着原型链向上查找,通过显示原型的prototype属性。xialuo对象也可以使用People对象的eat函数。原因是通过显示原型的__proto__隐式原型的属性。
我们通过浏览器直接调试,可以看到,xialuo.__proto__和Student.prototype是相等的。
总结:对于实例化xialuo.name属性或者执行方法eat时,先在自身属性和方法寻找。如果找不到则自动去__proto__中查找。
原型链的概念是JavaScript中非常重要的一个概念,因为它使得对象可以从其他对象中继承属性和方法,从而实现代码重用和简化。同时,原型链也是JavaScript中面向对象编程的基础。