為什么是直接在**原型(prototype)上**添加函數

這是一個非常經典、核心的 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要全部放到…