这是一个非常经典、核心的 JavaScript 面向对象编程问题:

> 为什么是直接在**原型(prototype)上**添加函数,而不是在类/构造函数内部直接添加?

你提到的代码中:

```javascript
function TopSearchComponent() {
// 构造函数逻辑
}

TopSearchComponent.prototype.initComponent = function () {
// 初始化方法
};
```

我们来详细解释这种写法背后的原理和好处。

---

## ✅ 一、JavaScript 的面向对象机制

JavaScript 是一种基于 **原型继承(Prototype-based Inheritance)** 的语言,而不是像 Java/C++ 那样使用类继承。虽然 ES6 引入了 `class` 关键字,但底层依然是基于原型的实现。

### 🧱 构造函数与原型的关系

- `function TopSearchComponent()` 是一个**构造函数**;
- 每个构造函数都有一个 `.prototype` 属性,它是一个对象,所有通过这个构造函数创建的实例都会共享这个原型对象;
- 实例的方法通常定义在原型上,而不是构造函数内部;

---

## 🔁 二、两种方式对比

### 方式一:在原型上定义方法(推荐)

```javascript
function TopSearchComponent() {}

TopSearchComponent.prototype.initComponent = function () {
console.log('初始化组件');
};

var component = new TopSearchComponent();
component.initComponent(); // 正常调用
```

✅ **优点:**

- 所有实例共享同一个方法;
- 节省内存;
- 支持继承链(可以通过修改原型实现继承);
- 更符合 OOP 的封装思想;

---

### 方式二:在构造函数内定义方法(不推荐)

```javascript
function TopSearchComponent() {
this.initComponent = function () {
console.log('初始化组件');
};
}

var component1 = new TopSearchComponent();
var component2 = new TopSearchComponent();

console.log(component1.initComponent === component2.initComponent); // false
```

❌ **缺点:**

- 每次创建实例时都会重新创建一个新的函数;
- 浪费内存资源;
- 不利于维护(如果要改方法,得每个实例都更新);
- 无法利用原型链进行继承;

---

## 🧠 三、为什么 Vue 或其他框架也这样用?

即使你在 Vue 项目中看到类似写法(如 AMD 模块中),也是为了:

- 将组件逻辑组织成类结构;
- 利用原型链实现方法共享;
- 提高性能和可维护性;
- 兼容老项目或模块系统(如 RequireJS);

---

## 📌 四、现代写法(ES6 class)

如果你使用的是现代 JS(Vue CLI / Webpack / Vite),可以更清晰地写为:

```javascript
class TopSearchComponent {
constructor() {
// 构造函数逻辑
}

    initComponent() {
console.log('初始化组件');
}
}
```

这其实是语法糖,等价于:

```javascript
function TopSearchComponent() {}

TopSearchComponent.prototype.initComponent = function () {
// ...
};
```

所以无论你是写 `class` 还是写 `prototype`,底层都是原型继承。

---

## ✅ 五、总结

| 写法 | 是否推荐 | 原因 |
|------|----------|------|
| 在原型上加方法 `.prototype.xxx` | ✅ 推荐 | 方法共享、节省内存、支持继承 |
| 在构造函数里加方法 `this.xxx = function(){}` | ❌ 不推荐 | 每次新建实例都创建新方法,浪费内存 |
| 使用 ES6 `class` | ✅ 推荐 | 语法更清晰,本质还是原型继承 |

---

## 💡 小贴士

- 如果某个方法需要访问实例状态(`this.xxx`),就放在原型上;
- 如果方法不依赖实例状态,也可以写成静态方法:

```javascript
TopSearchComponent.staticMethod = function () {};
```

或者:

```javascript
class TopSearchComponent {
static staticMethod() {}
}
```

---

如果你还想了解如何在 Vue 中结合原型链封装组件、如何实现继承、混入(mixins)等内容,欢迎继续提问 😊

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/90164.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/90164.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/90164.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解 classnames:React 动态类名管理的最佳实践

在现代前端开发中,我们经常需要根据组件的状态、属性或用户交互来动态切换 CSS 类名。虽然 JavaScript 提供了多种方式来处理字符串拼接,但随着应用复杂性的增加,传统的类名管理方式很快就会变得混乱不堪。这时,classnames 库就像…

C++系列(七):深度探索C++内存 --- 分区、堆栈、new/delete与高效编程实践

引言 程序运行的本质是对数据的处理,而内存则是程序执行的核心舞台。理解内存的物理与逻辑分区,是掌握程序底层行为、编写高效可靠代码的关键基石。内存并非混沌一片,而是被严格划分为代码区、全局区、栈区和堆区。每个区域拥有独特的生命周…

微信小程序71~80

1.总结小程序生命周期 小程序冷启动,钩子函数执行的顺序保留当前页面,进入下一个页面,钩子函数执行的顺序销毁当前页面,进入下一个页面,钩子函数执行的顺序小程序热启动,钩子函数执行的顺序 2.使用Componen…

[Pytest][Part 3]检测python package状态

目录 实现需求1: 检查python package状态——pkg_resource hook实现自动检测包状态 conftest.py hook钩子函数 Part1: https://blog.csdn.net/x1987200567/article/details/144915315?spm1001.2014.3001.5501 从这里开始逐个实现Part1中的需求 实现需求1&a…

自定义时间范围选择组件使用教程(基于 Vue 3 + Element Plus)

🕓 自定义时间范围选择组件使用教程(基于 Vue 3 Element Plus)✅ 一个灵活实用的时间范围选择器,支持开始时间、结束时间、快捷时间选项、本地双向绑定、插槽扩展等功能。–📘 一、功能介绍 该组件基于 Element Plus …

YOLOv8 模型转换 ONNX 后 C# 调用异常:一个参数引发的跨平台适配难题

一、问题背景:从 Python 训练到 C# 部署的跨平台需求 作为一名 C# 开发者,我在完成 YOLOv8 模型训练(使用 Ultralytics 官方框架,训练数据为自定义目标检测数据集,输入尺寸 640x640,训练轮次 100 轮&#…

Apache Cloudberry 亮相 2025 IvorySQL 生态大会暨 PostgreSQL 高峰论坛

6 月 27 日至 28 日,IvorySQL 2025 生态大会暨 PostgreSQL 高峰论坛在泉城济南顺利召开。本届大会由 IvorySQL 开源数据库社区主办、瀚高基础软件股份有限公司承办,吸引了来自国内外的数据库技术专家、开发者与开源爱好者齐聚一堂,聚焦数据库…

CMake之CMakeLists.txt语法规则

本文主要参考正点原子的应用开发手册,仅作为本人学习笔记使用。 目录 cmake 的使用方法其实还是非常简单的,重点在于编写 CMakeLists.txt,CMakeLists.txt 的语法规则也简单,并没有 Makefile的语法规则那么复杂难以理解&#xff01…

Mysql专题复习

重点内容:1. Mysql架构:客户端 Server层 存储引擎2. 索引数据结构:B树4. 索引优化:覆盖索引、排序、JOIN、分页; COUNT; 索引下推;单/双路排序5. 数据库事务; 锁;隔离级别&#xff…

CLIP的tokenizer详解

一、bytes_to_unicodedef bytes_to_unicode():"""Returns list of utf-8 byte and a corresponding list of unicode strings.The reversible bpe codes work on unicode strings.This means you need a large # of unicode characters in your vocab if you wa…

【如何判断Linux系统是Ubuntu还是CentOS】

要确定您的操作系统是 Ubuntu 还是 CentOS,可以通过以下方法快速检查: 方法 1:通过终端命令(推荐) 在终端中执行以下命令之一: 查看 /etc/os-release 文件 cat /etc/os-releaseUbuntu 特征:显示…

RISCV Linux 虚拟内存精讲系列二 -- Linux 入口 head.S

通过 Linux 的构建系统,即 Linux 源代码的根目录下的 Makefile,能够找到 vmlinux 的链接文件,从而能够查看其入口代码 head.S:_start, 如下: Linux 构建系统主Makefile: vmlinux.lds: head.S: 找到该入口后&#xff0c…

springAI学习:Advisors

spring AI Advisors类似于拦截器,会对请求的prompt做出特定的修改和增强(比如传入历史沟通记录、搜索信息等等),以达到完善prompt的目的。通过Advisors API,开发人员可以创建更为复杂、可重用、可维护的AI组件。下面介…

MySQL CDC与Kafka整合指南:构建实时数据管道的完整方案

一、引言:现代数据架构的实时化需求 在数字化转型浪潮中,实时数据已成为企业的核心资产。传统批处理ETL(每天T1)已无法满足以下场景需求: 实时风险监控(金融交易)即时个性化推荐(电商…

MATLAB | 绘图复刻(二十一)| 扇形热图+小提琴图

前段时间在小红书刷到了一个很有特色的热力图,由大佬滚筒洗衣机创作,感觉很有意思,尝试 MATLAB 复刻: 作者使用的是 python 代码,赶快去瞅瞅。 复刻效果 正文部分 0.数据准备 数据需要一个用来画热图的矩阵以及一个…

批量PDF转换工具,一键转换Word Excel

软件介绍 今天为大家推荐一款高效的Office文档批量转换工具,能够快速将Word和Excel文件批量转换为PDF格式。 软件特点 这款名为"五五Excel word批量转PDF"的工具体积小巧,不到2M大小,却能实现强大的批量转换功能&#xff0c…

面试150 基本计算器

思路 利用栈(stack)来保存进入括号前的计算状态(包括当前计算结果和符号),以便在括号结束后正确恢复计算上下文。代码通过遍历字符串,识别数字、加号、减号和括号。遇到数字时构造完整数值;遇到…

源哈希(sh)解析

源哈希(Source Hashing)是一种负载均衡算法,它根据请求的源 IP 地址(或其他标识符)生成哈希值,然后根据这个哈希值将请求分配到特定的后端服务实例。这种方法常用于确保来自同一客户端的请求始终被路由到同…

axios的使用以及封装

前言: 在现代前端开发中,网络请求是不可避免的核心功能之一。无论是获取后端数据、提交表单信息,还是与第三方 API 交互,高效且可靠的 HTTP 请求库至关重要。axios 作为一款基于 Promise 的 HTTP 客户端,凭借其简洁的 …

github上部署自己的静态项目

前置知识1、要在github部署项目要提交打包后的静态文件(html,css,js)到仓库里2、我们看下github所提供给我们的部署方式有啥,如下所见;要么是/root文件夹(就说仓库里全是打包后的产物:html,css,js要全部放到…