在 JavaScript 中,对象的属性和方法并不都存在于自身,有一部分存放在 原型对象(prototype) 中。理解“原型”与“原型链”,是掌握 JS 面向对象编程的关键。
对象的存储区域
对象的属性和方法主要有两个存储位置:
-
对象自身
- 通过
this.xxx = ...或者 实例字段 定义的属性 - 每个实例对象都会有独立的副本
class Person { name = 'linxi' // 实例字段(存在于对象自身) fn = () => console.log('haha') // 箭头函数也存在于对象自身 sayHello = '自身对象' // 普通属性 sayHello() { console.log('原型对象') // 方法存在于原型对象中 } } const d1 = new Person() console.log(d1.sayHello) // 优先访问自身对象属性 → '自身对象'注意:方法
sayHello(){}存放在 原型对象 上,而sayHello = '自身对象'存在 对象自身。访问时,自身优先级高于原型。 - 通过
访问原型对象
每个对象都有一个内部指针,指向它的原型对象。
常见访问方式有两种:
obj.__proto__(不推荐,非标准,已废弃)Object.getPrototypeOf(obj)(推荐,标准方法)
示例:
class Person {
sayHello() {
console.log('我在原型对象')
}
}
const p = new Person()
const obj = { name: 'obj' }
console.log(Object.getPrototypeOf(p)) // Person.prototype
console.log(p.__proto__) // 等价,但不推荐
console.log(p.__proto__.__proto__) // Object.prototype
console.log(p.__proto__.__proto__.__proto__) // null
如果在自身找不到属性,JS 会自动沿着 原型链 向上查找,直到 Object.prototype,再到 null。
原型链结构
来看一个继承的例子:
class God {
name = 'god'
sayHello() {
console.log('我便是自己的神')
}
}
class Person extends God {
name = 'person'
}
const GodInstance = new God()
const PersonInstance = new Person()
console.log('Person 原型链:')
console.log(PersonInstance.__proto__) // Person.prototype
console.log(PersonInstance.__proto__.__proto__) // God.prototype
console.log(PersonInstance.__proto__.__proto__.__proto__) // Object.prototype
console.log(PersonInstance.__proto__.__proto__.__proto__.__proto__) // null
// 验证
console.log(Person.prototype === PersonInstance.__proto__) // true
console.log(God.prototype === PersonInstance.__proto__.__proto__) // true
总结原型链:
PersonInstance → Person.prototype → God.prototype → Object.prototype → null
小结
-
自身属性优先级 > 原型属性
- 实例字段 / this.xxx 定义 → 自身
- class 方法 → 原型
-
访问原型
Object.getPrototypeOf(obj)obj.__proto__(非标准)
-
原型链查询规则
- 先查对象自身
- 再查对象的原型
- 一直向上,直到
Object.prototype - 若没找到 → 返回
undefined
-
继承的本质
- 子类的原型对象指向父类的实例
- 所以子类可以访问父类的属性和方法
适合面试的总结话术
JavaScript 的继承机制基于原型链:对象有一个
[[Prototype]]指针(可通过__proto__访问),它指向构造函数的prototype。访问属性时,JS 会先在对象自身查找,如果没有,则沿着原型链向上查找,直到Object.prototype或null。这也是 JS 实现继承、多态和代码复用的基础。