前端知识速记—JS篇:原型与原型链

前端知识速记---JS篇:原型与原型链

在JavaScript中,原型和原型链是非常重要的概念,它们帮助我们理解对象的创建和继承机制。


1. 什么是原型?

在JavaScript中,原型是构造函数所关联的一个对象,它决定了通过该构造函数创建的所有实例所共享的属性和方法。概念可以进一步分解为以下几点:

1.1 构造函数的原型属性

每个构造函数都有一个特殊的prototype属性,它是一个对象,定义了所有通过该构造函数创建的实例所可以共享的属性和方法。

示例:
javascript 复制代码
function Person(name) {
    this.name = name;  // 实例属性
}

// 定义共享方法
Person.prototype.sayHello = function() {
    console.log(`你好,我是${this.name}`);
};

// 创建实例
const alice = new Person('Alice');
alice.sayHello();  // 输出:你好,我是Alice

在这个例子中,Person构造函数的原型对象(Person.prototype)中定义了sayHello方法。所有使用Person构造函数创建的实例都可以访问这个方法。

1.2 实例与原型的关系

当你创建一个新实例时,该实例内部定义了一个指向其构造函数原型的__proto__属性。通过这个属性,实例可以访问原型上定义的方法和属性。

示例:
javascript 复制代码
console.log(alice.__proto__ === Person.prototype);  // 输出:true

这里,alice.__proto__指向了Person.prototype,因此alice可以访问到sayHello方法。

1.3 访问构造函数

每个实例对象都有一个constructor属性,指向它的构造函数。这使得我们可以从实例中反向确认它的创建来源。

示例:
javascript 复制代码
console.log(alice.constructor === Person);  // 输出:true

这告诉我们,alice是通过Person构造函数创建的。


2. 什么是原型链?

原型链是JavaScript中实现对象继承的关键机制。它是由多个原型构成的链条,每个对象都有一个__proto__属性,指向其构造函数的原型对象。以下是关于原型链的详细说明:

2.1 原型链的结构

每个对象都有一个__proto__属性,这个属性指向其构造函数的原型。原型对象同样可以有自己的原型,如此层层递归,直到找到顶层原型Object.prototype,或者为null为止,形成一个原型链。

示例:
javascript 复制代码
console.log(alice.__proto__ === Person.prototype);  // 输出:true
console.log(Person.prototype.__proto__ === Object.prototype);  // 输出:true
console.log(Object.prototype.__proto__);  // 输出:null

2.2 属性查找

当你访问一个对象的属性或方法时,JavaScript会首先检查该对象自身(即实例)是否有这个属性。如果没有,JavaScript将沿着原型链向上查找,直到找到该属性或者到达链的顶端。

示例:
javascript 复制代码
console.log(alice.name); // 输出:Alice (直接在实例上找到)
console.log(alice.sayHello); // 输出:function (通过原型找到)
console.log(alice.age); // 输出:undefined (在实例和原型上都找不到)

总之,如果在实例对象中找不到某个属性或方法,JavaScript会沿着__proto__属性链向上搜索,直到找到为止。

2.3 顶级原型

原型链的顶层原型是Object.prototype,它包含了所有JavaScript对象的基本方法和属性。如果在原型链的顶端也没有找到所请求的属性或方法,返回undefined

示例:
javascript 复制代码
console.log(Object.prototype);  // 输出:Object {}
console.log(alice.toString);     // 输出:查看在原型链上获取到的toString方法

3. 原型链的继承示例

通过原型链,我们可以让一个构造函数的实例继承另一个构造函数的属性和方法。

3.1 示例分析

javascript 复制代码
function Animal() {}

// 在Animal的原型上定义一个方法
Animal.prototype.eat = function() {
    console.log('正在吃...');
};

function Dog(name) {
    this.name = name;
}

// Dog的原型继承自Animal的实例
Dog.prototype = Object.create(Animal.prototype);

// 在Dog的原型上定义一个方法
Dog.prototype.bark = function() {
    console.log(`${this.name}在叫!`);
};

// 创建Dog的实例
const dog = new Dog('小狗');
dog.eat();  // 输出:正在吃...
dog.bark(); // 输出:小狗在叫!

在这个例子中,Dog的原型通过Object.create(Animal.prototype)指向Animal的原型。这意味着Dog的实例不仅能调用bark方法(它自己定义的方法),还可以调用eat方法(从Animal继承的方法)。

相关推荐
Wect2 分钟前
TypeScript 完全指南
前端·javascript·typescript
hunterandroid6 分钟前
Fragment 事务与状态丢失:从崩溃现场到稳定治理
前端
清风programmer6 分钟前
H5与小程序通信
前端·vue.js·uni-app
张元清7 分钟前
React useDeepCompareEffect:修复 useEffect 的对象依赖问题(2026)
javascript·react.js
不一样的少年_14 分钟前
原来 AI Agent 的核心循环这么简单:手搓一个 Agent Loop
前端·后端·agent
爱勇宝37 分钟前
你以为自己性格不好,其实只是被环境反复训练
前端·后端·程序员
phltxy40 分钟前
LangChain_v1_Agent快速开发和更新说明
前端·javascript·langchain
Cobyte40 分钟前
通过 Vite 运行手写的模板编译器
前端·javascript·vue.js
Hyyy41 分钟前
Agent 工作流
前端
Bigger41 分钟前
🔥每天最难的问题不是做饭,而是今天到底吃什么——我做了「烟火食间」
前端·人工智能·agent