前端知识速记—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继承的方法)。

相关推荐
前端之虎陈随易8 小时前
编程语言级别的Skill市场,AI Agent 的未来形态
前端·vue.js·人工智能·typescript·node.js
一路向北he8 小时前
字节钢铁军团--“提供情境,而非控制”
java·开发语言·前端
kyriewen8 小时前
豆包和千问同时关了智能体,我用它们搭的 3 个自动化全废了——迁移方案整理
前端·javascript·ai编程
前端一小卒9 小时前
我用 TypeScript 从零手写了一个 Claude Code,然后发现它的核心只有 30 行
前端·agent
铁皮饭盒9 小时前
用 Bun.cron 定时 7 月 7 日,为啥? 看图1
javascript
大圣编程10 小时前
Python中continue语句的用法是什么?
开发语言·前端·python
yuhaiqiang10 小时前
随手 vibecoding 的浏览器插件已经 6000 多次下载,聊聊他的产品设计
前端·后端·面试
之歆11 小时前
Vue商品详情与放大镜组件
前端·javascript·vue.js
再吃一根胡萝卜11 小时前
如何把小米 MiMo 接入 CodeBuddy,打造私有 Agent
前端
负责的蛋挞13 小时前
异步HttpModule的实现方式
java·服务器·前端