原型与原型链:继承的本质
原型与原型链:继承的本质
JS 没有类式继承(ES6 的 class 只是语法糖),对象之间靠原型共享属性。
两个关键概念
- 每个函数都有一个
prototype属性,它是一个对象 - 每个对象都有一个内部链接
__proto__,指向构造它的函数的prototype
function Person(name) {
this.name = name
}
Person.prototype.sayHi = function () {
console.log('hi, ' + this.name)
}
const p = new Person('Dong')
p.sayHi()
console.log(p.__proto__ === Person.prototype) // true
console.log(Person.prototype.constructor === Person) // true
所有实例共享同一个原型对象,方法放在原型上,内存里只存一份。
属性查找:沿原型链向上
访问 p.sayHi 时,先在 p 自身找;找不到就去 p.__proto__(Person.prototype)找;还找不到,继续往上到 Object.prototype;终点是 null。这条链条就是原型链。
p.toString() // p 没有 → Person.prototype 没有 → Object.prototype 有
p.__proto__.__proto__ === Object.prototype // true
Object.prototype.__proto__ // null,链条终点
实现继承
function Student(name, grade) {
Person.call(this, name) // 借用父构造函数,继承实例属性
this.grade = grade
}
Student.prototype = Object.create(Person.prototype) // 原型接链
Student.prototype.constructor = Student
const s = new Student('Dong', 3)
s.sayHi() // 沿原型链找到 Person.prototype 上的方法
ES6 之后直接写 class Student extends Person,底层还是这套机制。排查问题时注意:用 hasOwnProperty 区分属性是自身的还是原型上的;不要随便改内置对象的原型(如 Array.prototype),会污染全局。
看到这里了?如果这篇文章帮到过你
请我喝瓶可乐就好 🥤

评论0 条
还没有评论,来抢沙发~