《原型链的故事: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
相关推荐
程序员大阳8 小时前
HTML+CSS+JS对话式实战(3)-活动管理页实现查询、新增、删除API后端接口
javascript·css·html·实战·删除·查询·新增
炫酷的大高个9 小时前
6 亿播放的闪身步,我用前端算出 15 倍重心差
前端·javascript
林小帅10 小时前
【笔记】Prisma v7 + SQLite TS2305 及连锁 TS7006 问题
前端·javascript·后端
Dumbness10 小时前
订阅消息弹窗必须在用户点击里调:联调实验室里 timing 和 Mock 支付通知踩的坑
javascript·uni-app
黄连木笛10 小时前
不改一行 Postman 源码,把它汉化了:Electron preload 注入 + fetch 拦截实战
javascript·electron
叼烟扛炮11 小时前
[LangChain] 学习笔记(03):打破失忆症——对话机制与上下文管理
java·前端·javascript·笔记·学习·langchain
卋罖75012 小时前
Razor 视图 + JavaScript + Vue/iView 组件实现的表格自定义列
javascript·vue·iview·razor视图
系统集成-鹰翔1 天前
ERP图片改名后仍命中识别缓存:缓存键、十分钟到期与调用计数
javascript·经验分享·后端
FlyWIHTSKY1 天前
vue2和vue3有什么区别,用法上有哪些区别
前端·javascript·vue.js
程序员大阳1 天前
副队长JavaScript教程(66)-本地存储实战:待办事项网页的开发
javascript·json·实战·待办事项·本地存储·案例