《原型链的故事:JavaScript 对象模型的秘密》

原型链(Prototype Chain) 是 JavaScript 中实现继承的核心机制。每个对象都有一个内部属性 [[Prototype]](可以通过 __proto__ 访问),指向其原型对象。每个对象都有一个原型, 原型本身也是一个对象因此它也有自己的原型 。通过原型链,对象可以访问其原型对象的属性和方法。以下是原型链的详细说明:

获取原型的方法

方法 说明
obj.__proto__ 非标准方法,直接访问对象的原型。
Object.getPrototypeOf(obj) 标准方法,推荐使用。
Object.prototype.isPrototypeOf(obj) 检查对象是否在原型链上。
obj.constructor.prototype 通过构造函数获取原型。

1. 原型对象

  • 每个函数都有一个 prototype 属性,指向一个对象(称为原型对象)。

  • 当使用 new 关键字创建实例时,实例的 __proto__ 会指向构造函数的 prototype

示例

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

// 在原型对象上添加方法
Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name}`);
};

const person1 = new Person('Alice');
person1.sayHello(); // 输出: Hello, my name is Alice
  • person1.__proto__ 指向 Person.prototype

  • Person.prototype.constructor 指向 Person 函数。

2. 原型链

  • 当访问对象的属性或方法时,JavaScript 会先在对象自身查找,如果找不到,则沿着原型链向上查找,直到找到或到达原型链的顶端(null)。

  • 原型链的顶端是 Object.prototype,其 __proto__null

示例

javascript 复制代码
console.log(person1.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true

3. 继承

通过原型链,可以实现对象之间的继承。

(1)构造函数继承

javascript 复制代码
function Parent(name) {
  this.name = name;
}
Parent.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name}`);
};

function Child(name, age) {
  Parent.call(this, name); // 调用父类构造函数
  this.age = age;
}

// 设置原型链
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

const child = new Child('Bob', 10);
child.sayHello(); // 输出: Hello, my name is Bob

(2)ES6 类继承

javascript 复制代码
class Parent {
  constructor(name) {
    this.name = name;
  }
  sayHello() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

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

const child = new Child('Bob', 10);
child.sayHello(); // 输出: Hello, my name is Bob

4. 原型链的查找过程

当访问对象的属性或方法时,JavaScript 会按照以下顺序查找:

  1. 在对象自身查找。

  2. 如果找不到,沿着 __proto__ 向上查找,直到找到或到达 null

示例

javascript 复制代码
const obj = { a: 1 };
console.log(obj.toString()); // 输出: [object Object]
  • obj 自身没有 toString 方法。

  • 查找 obj.__proto__(即 Object.prototype),找到 toString 方法。

5. 修改原型链

可以通过修改 __proto__prototype 来改变原型链。

示例

javascript 复制代码
const parent = { name: 'Parent' };
const child = { age: 10 };

// 设置 child 的原型为 parent
child.__proto__ = parent;

console.log(child.name); // 输出: Parent
相关推荐
星栈独行1 小时前
翻完 Pi 源码:它和 Codex、Claude Code 有何不同
开发语言·javascript·人工智能·程序人生
落落Plus2 小时前
浏览器缓存机制详解
javascript·缓存·浏览器缓存
浅水壁虎4 小时前
vue基础(第二章 )
前端·javascript·vue.js
界面开发小八哥4 小时前
界面控件DevExtreme v26.1新版亮点——支持Angular 22
前端·javascript·angular.js·devexpress·ui开发·devextreme
mONESY5 小时前
React useState 核心原理与最佳实践:从异步更新到性能优化全解
javascript
腻害兔5 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:CRM 客户关系模块深度解析——从线索到回款,一套完整的 B2B 销售闭环是怎么搭的?
java·前端·javascript·vue.js·产品经理·ai编程
gis开发之家6 小时前
《Vue3 从入门到大神37篇》Vue3 源码详解(七):watch 与 watchEffect 源码对比——副作用是如何被追踪的?
javascript·前端框架·vue3·vue3源码
bloglin999998 小时前
langchain 和 langgraph 和 react
javascript·react.js·langchain
触底反弹8 小时前
🚀 删了数据刷新又回来?3 组件 × 4 回调 × 3 坑讲透 React 父子通信
前端·javascript·react.js
会周易的程序员10 小时前
js-shm: 高性能 Node.js 共享内存模块
开发语言·javascript·c++·node.js·共享内存·shm