【前端八股文面试题】【JavaScript篇7】什么是JavaScript的原型、原型链? 有什么特点
文章目录
- 一、原型(Prototype)
- 二、原型链(Prototype Chain)
- 三、核心特点
- 四、原型 vs 类(ES6 class)
- 总结
JavaScript的原型(Prototype)和原型链(Prototype Chain)是理解其面向对象特性的核心机制,也是实现继承的基础。以下是详细的解释和特点:
一、原型(Prototype)
-
定义
- 每个 函数 都有一个特殊的属性
prototype
(显式原型)。 prototype
是一个对象,用于存储该构造函数创建的实例共享的属性和方法。- 例如:
function Person(name) {this.name = name; } // 向原型添加共享方法 Person.prototype.sayHello = function() {console.log(`Hello, I'm ${this.name}`); };
- 每个 函数 都有一个特殊的属性
-
关键点
- 构造函数的
prototype
属性指向其原型对象。 - 实例对象通过
__proto__
(隐式原型,非标准属性)或Object.getPrototypeOf()
访问原型。 - 原型对象中默认包含
constructor
属性,指回构造函数本身(如Person.prototype.constructor === Person
)。
- 构造函数的
二、原型链(Prototype Chain)
-
定义
- 当访问一个对象的属性或方法时:
- 先在该对象自身查找。
- 找不到则通过
__proto__
查找其原型。 - 若原型中仍找不到,则继续向原型的原型查找(即原型链层层向上)。
- 直到找到属性或到达顶层原型(
Object.prototype.__proto__ === null
)。
- 当访问一个对象的属性或方法时:
-
结构示例
const john = new Person("John");
原型链关系:
john → Person.prototype → Object.prototype → null
john.sayHello()
调用流程:john
自身无sayHello
→ 通过john.__proto__
找到Person.prototype.sayHello
。
john.toString()
调用流程:john
和Person.prototype
均无toString
→ 最终在Object.prototype
中找到。
三、核心特点
-
动态性
- 原型对象上的修改实时生效,所有实例均可立即访问。
Person.prototype.age = 30; console.log(john.age); // 30(即使john是之前创建的)
-
共享性
- 原型上的属性和方法被所有实例共享,节省内存。
- 但引用类型属性(如数组)的修改会跨实例共享(需谨慎):
Person.prototype.hobbies = []; john.hobbies.push("Coding"); const alice = new Person("Alice"); console.log(alice.hobbies); // ["Coding"](所有实例共享同一数组)
-
继承机制
- 通过原型链实现对象之间的继承关系。
function Student(grade) {this.grade = grade; } // 继承Person的原型 Student.prototype = Object.create(Person.prototype); Student.prototype.constructor = Student; // 修复constructor指向
- 通过原型链实现对象之间的继承关系。
-
原型链终点
- 所有原型链的终点是
Object.prototype
(其__proto__
为null
)。 - 内置方法(如
toString()
、hasOwnProperty()
)均定义于此。
- 所有原型链的终点是
-
性能注意
- 过长的原型链(如多层继承)会降低属性查找效率。
- 可通过
hasOwnProperty()
区分自身属性和继承属性。
四、原型 vs 类(ES6 class)
class
语法是原型的语法糖,底层仍基于原型链。class
中的extends
和super
本质是原型继承的封装:class Student extends Person {constructor(name, grade) {super(name); // 调用父类构造函数this.grade = grade;} }
总结
概念 | 作用 | 访问方式 |
---|---|---|
原型 | 存储构造函数共享的属性和方法 | Constructor.prototype |
原型链 | 通过 __proto__ 实现属性查找的链式结构 | obj.__proto__ (或 Object.getPrototypeOf(obj) ) |
顶层原型 | Object.prototype ,含内置方法 | Object.prototype.__proto__ === null |
理解原型和原型链是掌握JavaScript继承、类实现、设计模式的关键。