JavaScript創建對象的多種方式

在JavaScript中,創建對象有多種方式,每種方式都有其優缺點。本文將介紹四種常見的對象創建模式:工廠模式、構造函數模式、原型模式和組合模式,并分析它們的特點以及如何優化。

1. 工廠模式

工廠模式是一種簡單的對象創建方式,它使用一個函數來封裝創建對象的細節。

function createPerson(name, age) {const obj = new Object();obj.name = name;obj.age = age;obj.sayName = function() {console.log(this.name);};return obj;
}const person1 = createPerson("Alice", 25);
const person2 = createPerson("Bob", 30);

1.1. 優點

1. 簡單易用,避免了重復代碼;

2. 可以創建多個相似對象;

1.2. 缺點

1. 創建的對象無法識別類型,因為都是Object類型;

2. 每個對象都有自己獨立的方法實例,造成內存浪費;

1.3. 優化方案

可以將方法移到工廠函數外部,減少內存消耗;

function sayName() {console.log(this.name);
}function createPerson(name, age) {const obj = new Object();obj.name = name;obj.age = age;obj.sayName = sayName;return obj;
}

2. 構造函數模式

構造函數模式使用new操作符來創建特定類型的對象。

function Person(name, age) {this.name = name;this.age = age;this.sayName = function() {console.log(this.name);};
}const person1 = new Person("Alice", 25);
const person2 = new Person("Bob", 30);

2.1. 優點

1.?可以識別對象類型,通過instanceof檢測;

2.?符合傳統的面向對象語言創建對象的方式;

2.2. 缺點

1.?每個方法都要在每個實例上重新創建一遍,造成內存浪費;

2.?如果方法很多,會占用大量不必要的內存;

2.3.?優化方案

將方法定義在構造函數外部

function Person(name, age) {this.name = name;this.age = age;this.sayName = sayName;
}function sayName() {console.log(this.name);
}

3. 原型模式

原型模式利用原型鏈來實現屬性和方法的共享。

function Person() {}Person.prototype.name = "Default";
Person.prototype.age = 0;
Person.prototype.sayName = function() {console.log(this.name);
};const person1 = new Person();
person1.name = "Alice";
person1.age = 25;const person2 = new Person();
person2.name = "Bob";
person2.age = 30;

3.1.? 優點

1.?所有對象實例共享原型上的屬性和方法,節省內存;

2.?可以在運行時動態修改原型,影響所有實例;

3.2.? 缺點

1.?所有實例默認取得相同的屬性值,不太靈活;

2.?對于包含引用類型值的屬性,如數組,一個實例修改會影響所有實例;

3.3.??優化方案

組合使用構造函數模式和原型模式

4. 組合模式(構造函數+原型)

組合模式是使用最廣泛、認同度最高的一種創建自定義類型的方法。

function Person(name, age) {// 實例屬性this.name = name;this.age = age;
}// 共享方法
Person.prototype = {constructor: Person,sayName: function() {console.log(this.name);}
};const person1 = new Person("Alice", 25);
const person2 = new Person("Bob", 30);

4.1.?優點

1. 每個實例有自己的屬性副本;

2. 所有實例共享方法引用,節省內存;

3. 可以向構造函數傳遞參數,靈活性高;

4. 是目前ECMAScript中使用最廣泛的方式;

4.2.?缺點

1.?構造函數和原型分開定義,可能讓代碼組織不夠清晰;

2.?對于習慣其他語言的開發者來說,這種模式可能不太直觀;

4.3.?優化方案

使用動態原型模式,將所有信息封裝在構造函數中。

function Person(name, age) {// 屬性this.name = name;this.age = age;// 方法(只在第一次調用構造函數時添加到原型)if (typeof this.sayName !== "function") {Person.prototype.sayName = function() {console.log(this.name);};}
}

注意:使用動態原型模式時,不能用對象字面量重寫原型。
?

function Person(name) {this.name = name;if (typeof this.getName != "function") {Person.prototype = {constructor: Person,getName: function () {console.log(this.name);}}}
}var person1 = new Person('Jack1');
var person2 = new Person('Jack2');// 報錯 并沒有該方法
person1.getName();// 注釋掉上面的代碼,這句是可以執行的。
person2.getName();

開始執行 var person1 = new Person('Jack1')

new 的執行過程:

1. 首先新建一個對象;

2. 然后將對象的原型指向 Person.prototype;

3. 然后 Person.apply(obj);

4. 返回這個對象;

注意這個時候,回顧下 apply 的實現步驟,會執行 obj.Person 方法,這個時候就會執行 if 語句里的內容,注意構造函數的 prototype 屬性指向了實例的原型,使用字面量方式直接覆蓋 Person.prototype,并不會更改實例的原型的值,person1 依然是指向了以前的原型,而不是 Person.prototype。而之前的原型是沒有 getName 方法的,所以就報錯了。

如果你就是想用字面量方式寫代碼,可以嘗試下這種:

function Person(name) {this.name = name;if (typeof this.getName != "function") {Person.prototype = {constructor: Person,getName: function () {console.log(this.name);}}return new Person(name)}
}var person1 = new Person('Jack1');
var person2 = new Person('Jack2');// 報錯 并沒有該方法
person1.getName();// 注釋掉上面的代碼,這句是可以執行的。
person2.getName();

5. 總結

在實際開發中,組合模式(構造函數+原型)是最常用的方式,它結合了構造函數模式和原型模式的優點,避免了各自的缺點,是創建自定義類型的首選方法。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/74592.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74592.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/74592.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

muduo庫的思路梳理

前言 對于muduo庫源碼的剖析我發現還是有些混亂的,所以這里再次梳理一下muduo網絡庫爭取可以簡單明了 首先對于muduo庫來說,不能想的得太過于復雜,它無非就是一個線程池加上epoll組成的網絡庫 這里我們從用的角度出發理解muoduo網絡庫 #inc…

Keil5 安裝全攻略

Keil5 安裝全攻略 Keil5 是一款廣泛用于嵌入式開發的 IDE,支持多種微控制器架構(如 ARM、C51)。本文將詳細介紹 Keil5 的安裝步驟、常見問題及解決方法,幫助您快速上手。 1. 安裝前的準備工作 (1) 系統要求 操作系統&#xff1…

C語言do...while語句將數字反轉后輸出

一、題目引入 輸入一個數字,將各位數字反轉后輸出? 參考代碼: 二、分析代碼 接著圖片中的分析 第一 ->a 的值變為12 第二 ->進入while循環條件,a為12不等于0循環才停止(a的值為12,顯然不等于0) 所以繼續進行循環 第三 ->此時b的值為12取各位上的數字(即2) 打印…

優選算法系列(前綴和 _下) k

目錄 五:和為 k 的子數組(medium) 題目鏈接:560. 和為 K 的子數組 - 力扣(LeetCode) 解法: 代碼: 六:和可被 K 整除的子數組(medium) 題目鏈…

mac m3 pro 部署 stable diffusion webui

什么是Stable Diffusion WebUI ? Stable Diffusion WebUI 是一個基于Stable Diffusion模型開發的圖形用戶界面(GUI)工具。通過這個工具,我們可以很方便的基于提示詞,描述一段文本來指導模型生成相應的圖像。相比較通過…

OpenCV圖像拼接(6)根據權重圖對源圖像進行歸一化處理函數normalizeUsingWeightMap()

操作系統:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 編程語言:C11 算法描述 cv::detail::normalizeUsingWeightMap 是 OpenCV 中用于圖像拼接細節處理的一個函數。它根據權重圖對源圖像進行歸一化處理,通常用于…

23種設計模式-外觀(Facade)設計模式

外觀設計模式 🚩什么是外觀設計模式?🚩外觀設計模式的特點🚩外觀設計模式的結構🚩外觀設計模式的優缺點🚩外觀設計模式的Java實現🚩代碼總結🚩總結 🚩什么是外觀設計模式…

capl語言基礎語法(二)

1.strncpy:將字符串復制到另一個字符串中。 輸入: dest 是目標字符串。 src 是源字符串。 n 是要復制的最大字符數。 語法: char *strncpy(char *dest, const char *src, size_t n); 例子: strncpy(gStringRep,"",…

QLoRA和LoRA 微調

QLoRA 其實是一種結合了量化和 LoRA 微調技術的統一方法,而不是同時使用兩種不同的微調方式。換句話說,QLoRA 的意思就是:先把大模型的主權重用低精度(例如 4-bit)量化,從而大幅減少存儲需求;然…

Qt Concurrent 并發 Map 和 Map-Reduce

并發 Map 和 Map-Reduce QtConcurrent::map()會對容器中的每個項目應用一個函數,對項目進行就地修改。QtConcurrent::mapped() 類似于 map(),但它返回的是一個包含修改內容的新容器。QtConcurrent::mappedReduced() 類似于 mapped(),只不過修…

RT-Thread-線程管理

一、線程管理 RT_Thread線程管理主要是實現線程管理和調度,線程分為用戶線程和系統線程。RT_Thread的線程調度器是搶占式的,尋找就緒狀態最高優先級線程。 線程管理的API函數 創建線程函數 rt_thread_t rt_thread_create( const char *name, //線程名稱 …

【CC2530 教程 十二】CC2530 Z-Stack 硬件抽象層

目錄 一、硬件抽象層簡介: (1)HAL 硬件抽象層是什么? (2)通俗易懂的解釋: (3)具體例子: 二、硬件抽象層HAL: (1)HAL…

Linux如何判斷磁盤是否已分區?

在 Linux 系統中,判斷磁盤是否已分區可通過以下方法實現: 方法 1:使用 fdisk -l 命令 此命令會列出所有磁盤及其分區的詳細信息: sudo fdisk -l輸出解讀: 若磁盤(如 /dev/sdb)下有類似 /dev/…

《熔化焊接與熱切割作業》考試注意事項

考試前的準備 攜帶必要的證件和材料:考生需攜帶身份證、準考證等有效證件,以及考試所需的焊接工具、材料等。確保證件齊全,避免因證件問題影響考試。 提前檢查焊接設備和工具:在考試前,考生應仔細檢查焊接設備和工具是…

Matlab Hessian矩陣計算(LoG算子)

文章目錄 一、簡介二、實現代碼三、實現效果參考資料一、簡介 圖像的Hessian矩陣用于描述圖像灰度值的二階導數,可以用來分析圖像的局部曲率和變化。例如,在圖像邊緣檢測、特征點檢測等任務中,Hessian矩陣能幫助我們識別圖像的結構。 Hessian矩陣定義 對于二維圖像,Hessian…

selenium之處理彈框(alert、confirm、prompt)

彈框 WebDriver提供了一個API, 用于處理JavaScript提供的三種類型的原生彈窗消息. 這些彈窗由瀏覽器提供限定的樣式.;分別為以下三種 alerts警告框confirm確認框prompt提示框 話不多說,開始實踐下就知道怎么一回事了 alerts 警告框,顯示…

Visual Studio 2019 Qt QML 項目環境搭建常見問題處理方法

在 Visual Studio 2019 運行 Qt/QML 項目比直接使用QtCreator環境麻煩,主要是有qmake 的一些配置項不能在 Visual Studio中設置。下面整理一些常見問題的處理方法,供參考: 搭建VS Qt 環境,在Visual Studios 2019下面安裝 Qt Vis…

【Linux】POSIX信號量與基于環形隊列的生產消費者模型

目錄 一、POSIX信號量: 接口: 二、基于環形隊列的生產消費者模型 環形隊列: 單生產單消費實現代碼: RingQueue.hpp: main.cc: 多生產多消費實現代碼: RingQueue.hpp: main.…

RAG優化:python從零實現GraphRag 一場文檔與知識的“戀愛”之旅

嘿,親愛的算法工程師們,準備好迎接一場文檔與知識的“戀愛”之旅了嗎?今天我們要介紹的 Graph RAG,就像是一位“紅娘”,幫助文檔和知識在圖的世界里找到彼此,擦出智慧的火花! 文章目錄 為什么需要 Graph RAG?Graph RAG 的“戀愛秘籍”準備好了嗎?讓我們開始吧!環境設…

深入 SVG:矢量圖形、濾鏡與動態交互開發指南

1.SVG 詳細介紹 SVG(Scalable Vector Graphics) 是一種基于 XML 的矢量圖形格式,用于描述二維圖形。 1. 命名空間 (Namespace) ★ 了解 命名空間 URI:http://www.w3.org/2000/svg 用途:在 XML 或 XHTML 中區分不同標…