首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >深入理解 JavaScript 原型、原型链与继承机制

深入理解 JavaScript 原型、原型链与继承机制

原创
作者头像
用户7462196
发布2026-02-07 17:20:36
发布2026-02-07 17:20:36
1290
举报

深入理解 JavaScript 原型、原型链与继承机制

在 JavaScript 的世界里,原型(Prototype)原型链(Prototype Chain)继承(Inheritance) 是核心且容易混淆的概念。它们共同构成了 JavaScript 面向对象编程(OOP)的基础,也是面试中高频考察的知识点。本文将从底层原理出发,层层递进,帮助你彻底掌握这三者的关系与运作机制。


一、为什么 JavaScript 需要原型?

与其他面向对象语言(如 Java、C++)不同,JavaScript 并没有“类”的概念(ES6 的 class 也只是语法糖),而是基于 对象 构建一切。为了实现对象之间的属性和方法共享,JavaScript 引入了 原型机制

简单来说:原型是对象之间共享属性和行为的一种机制


二、什么是原型(Prototype)?

每个 JavaScript 函数(除了箭头函数)在创建时都会自动拥有一个名为 prototype 的属性,它指向一个对象——这就是 原型对象

代码语言:javascript
复制
function Person(name) {
  this.name = name;
}

console.log(Person.prototype); // { constructor: Person }

同时,每个对象(包括实例对象)内部都有一个隐式属性 [[Prototype]](在大多数浏览器中可通过 __proto__ 访问),它指向其构造函数的 prototype 对象。

代码语言:javascript
复制
const p1 = new Person('Alice');
console.log(p1.__proto__ === Person.prototype); // true

✅ 关键点:

  • prototype函数的属性。
  • __proto__(或 [[Prototype]])是对象的内部属性。
  • 实例对象通过 __proto__ 链接到构造函数的 prototype

三、原型链(Prototype Chain)是如何工作的?

当访问一个对象的属性时,JavaScript 引擎会按以下顺序查找:

  1. 先在对象自身查找;
  2. 如果找不到,就沿着 __proto__ 向上查找其原型对象;
  3. 如果原型对象也没有,继续向上查找原型的原型;
  4. 直到找到 Object.prototype
  5. 若仍未找到,则返回 undefined

这个逐级向上查找的链条,就是 原型链

代码语言:javascript
复制
function Animal() {}
Animal.prototype.eat = function() { console.log('eating...'); };

function Dog() {}
Dog.prototype = new Animal(); // 继承 Animal
Dog.prototype.bark = function() { console.log('barking!'); };

const dog = new Dog();
dog.bark(); // barking!
dog.eat();  // eating! (从 Animal.prototype 继承而来)

// 原型链示意:
// dog → Dog.prototype → Animal.prototype → Object.prototype → null

🌟 所有原型链的终点都是 Object.prototype,而 Object.prototype.__proto__null,表示链的终结。


四、JavaScript 中的继承如何实现?

由于 JavaScript 没有传统意义上的“类继承”,它通过 原型链 来模拟继承行为。以下是几种常见的继承方式:

1. 原型链继承(Prototype Chain Inheritance)

代码语言:javascript
复制
function Parent() { this.name = 'parent'; }
Parent.prototype.say = function() { return this.name; };

function Child() {}
Child.prototype = new Parent(); // 关键:让 Child.prototype 指向 Parent 实例

const c = new Child();
console.log(c.say()); // 'parent'

缺点:所有子实例共享父类引用类型属性,且无法向父构造函数传参。


2. 借用构造函数(Constructor Stealing)

代码语言:javascript
复制
function Parent(name) { this.name = name; }
function Child(name) {
  Parent.call(this, name); // 借用父构造函数
}

优点:可传参,避免引用共享。 缺点:无法继承父类原型上的方法。


3. 组合继承(最常用)

结合原型链 + 借用构造函数:

代码语言:javascript
复制
function Parent(name) {
  this.name = name;
}
Parent.prototype.say = function() { return this.name; };

function Child(name, age) {
  Parent.call(this, name);   // 借用构造函数,传参 + 避免共享
  this.age = age;
}
Child.prototype = new Parent(); // 原型链继承方法
Child.prototype.constructor = Child; // 修正 constructor

const c = new Child('Tom', 10);
console.log(c.say(), c.age); // 'Tom', 10

4. ES6 的 classextends

ES6 引入了 class 语法糖,底层仍是基于原型链:

代码语言:javascript
复制
class Parent {
  constructor(name) { this.name = name; }
  say() { return this.name; }
}

class Child extends Parent {
  constructor(name, age) {
    super(name); // 调用父类构造函数
    this.age = age;
  }
}

class 写法更清晰,但理解其背后的原型机制依然至关重要。


五、常见误区澄清

误区

正确理解

“prototype 是所有对象都有的属性”

❌ 只有函数才有 prototype;对象有 __proto__

“修改 __proto__ 会影响构造函数的 prototype”

❌ 它们是引用关系,但直接修改 __proto__ 不推荐(性能差)

“instanceof 判断的是构造函数”

❌ 实际是检查对象的原型链中是否包含构造函数的 prototype

代码语言:javascript
复制
[] instanceof Array; // true
// 等价于:Array.prototype 是否在 [] 的原型链上?

六、总结

  • 原型(Prototype):函数的 prototype 属性,用于共享方法。
  • 原型链(Prototype Chain):对象通过 __proto__ 逐级向上查找属性的机制。
  • 继承:通过设置子类原型指向父类实例(或使用 Object.create()class extends)实现。

理解这三者的关系,就掌握了 JavaScript 面向对象的“灵魂”。无论你使用的是传统函数构造器,还是现代 class 语法,其底层逻辑始终围绕 原型链 展开。

💡 记住一句话“在 JavaScript 中,万物皆对象,对象皆有原型,原型构成链条,链条实现继承。”

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 深入理解 JavaScript 原型、原型链与继承机制
    • 一、为什么 JavaScript 需要原型?
    • 二、什么是原型(Prototype)?
    • 三、原型链(Prototype Chain)是如何工作的?
    • 四、JavaScript 中的继承如何实现?
      • 1. 原型链继承(Prototype Chain Inheritance)
      • 2. 借用构造函数(Constructor Stealing)
      • 3. 组合继承(最常用)
      • 4. ES6 的 class 与 extends
    • 五、常见误区澄清
    • 六、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档