JavaScript創建對象與構造函數

目錄

創建對象

一、創建對象的 5 種核心方式

1. 對象字面量(直接量)

2. 使用?Object.create()

3. 工廠模式

4. 構造函數模式

5. ES6?class?語法(語法糖)

二、構造函數與?new?關鍵字

1. 構造函數的作用

2. 構造函數的特征

3.?new?關鍵字的執行機制

三、構造函數 vs 工廠函數對比

四、原型鏈與構造函數的關系

五、常見問題與解決方案

1. 忘記使用?new?導致問題

2. 方法重復創建(內存浪費)

六、總結

實例成員與靜態成員

一、實例成員(Instance Members)

1. 定義與特點

2. 內存模型

二、靜態成員(Static Members)

1. 定義與特點

2. ES6?class?中的靜態成員

三、實例成員 vs 靜態成員

四、關鍵使用場景

1. 實例成員的典型應用

2. 靜態成員的典型應用

五、繼承與靜態成員

1. ES6?class?的靜態繼承

2. ES5 手動實現靜態繼承

六、常見問題與解決方案

1. 靜態方法中訪問實例成員

2. 實例方法誤用?this?訪問靜態成員


創建對象

一、創建對象的 5 種核心方式

1. 對象字面量(直接量)

特點:最簡潔的方式,適合創建簡單對象。

const person = {name: "Alice",age: 30,greet() {console.log(`Hello, I'm ${this.name}`);}
};

2. 使用?Object.create()

特點:基于現有對象原型創建新對象,適合原型繼承。

const prototypeObj = { type: "Human" };
const person = Object.create(prototypeObj);
person.name = "Bob";

3. 工廠模式

特點:通過函數封裝對象創建邏輯,避免重復代碼。

function createPerson(name, age) {return {name,age,greet() {console.log(`Hi, I'm ${this.name}`);}};
}
const person = createPerson("Charlie", 25);

4. 構造函數模式

特點:結合?new?關鍵字創建對象,支持實例化。

function Person(name, age) {this.name = name;this.age = age;this.greet = function() {console.log(`Hello, I'm ${this.name}`);};
}
const person = new Person("David", 28);

5. ES6?class?語法(語法糖)

特點:基于原型的面向對象語法糖,更接近傳統面向對象語言。

class Person {constructor(name, age) {this.name = name;this.age = age;}greet() {console.log(`Hi, I'm ${this.name}`);}
}
const person = new Person("Eve", 32);

二、構造函數與?new?關鍵字

1. 構造函數的作用

定義:用于創建對象的模板函數,通常與?new?關鍵字配合使用。

  • 初始化對象:定義對象屬性和方法。

  • 標識對象類型:通過?instanceof?可檢測對象類型。

  • 綁定原型鏈:通過?prototype?屬性實現繼承。

示例:

function Person(name, age) {this.name = name;  // 實例屬性this.age = age;
}

使用?new?的實例化過程:

  1. 創建空對象,其?__proto__?指向?Person.prototype

  2. 執行構造函數,將?this?綁定到新對象。

  3. 返回新對象(若構造函數無顯式返回對象)。

2. 構造函數的特征

  • 命名約定:通常首字母大寫(如?Person),便于區分普通函數。

  • 強制使用?new:若不使用?newthis?會指向全局對象(嚴格模式下為?undefined),導致意外行為。

    // 錯誤示例(未使用 new)
    const p = Person("Frank"); 
    console.log(window.name); // "Frank"(污染全局)

3.?new?關鍵字的執行機制

當使用?new?調用構造函數時,發生以下步驟:

function Person(name) {this.name = name;
}// new 的底層模擬(簡化版)
function myNew(constructor, ...args) {// 1. 創建一個新對象,并鏈接到構造函數的原型const obj = Object.create(constructor.prototype);// 2. 執行構造函數,將 this 綁定到新對象const result = constructor.apply(obj, args);// 3. 返回對象(如果構造函數返回對象,則優先返回它)return typeof result === 'object' ? result : obj;
}const person = myNew(Person, "Alice");

詳細步驟

  1. 創建空對象:創建一個新對象?obj,其隱式原型(__proto__)指向構造函數的?prototype

  2. 綁定?this:將構造函數內的?this?指向新對象?obj,并執行構造函數代碼。

  3. 處理返回值:若構造函數返回一個對象,則返回該對象;否則返回?obj


三、構造函數 vs 工廠函數對比

特性構造函數工廠函數
創建方式new Person()createPerson()
原型鏈實例的?__proto__?指向構造函數原型默認無原型鏈綁定
類型檢測instanceof?有效instanceof?無法識別
性能稍優(引擎優化)略低
代碼復用通過原型方法共享每個對象獨立方法(內存冗余)

四、原型鏈與構造函數的關系

  • 構造函數:通過?prototype?屬性定義共享方法。

  • 實例對象:通過?__proto__?訪問原型鏈。

  • 繼承機制:實例可訪問構造函數原型上的屬性和方法。

示例

function Person(name) {this.name = name;
}// 在原型上添加方法(共享)
Person.prototype.greet = function() {console.log(`Hi, I'm ${this.name}`);
};const person = new Person("Grace");
person.greet(); // 調用原型方法

五、常見問題與解決方案

1. 忘記使用?new?導致問題

解決方案:在構造函數內部強制?new?調用。

function Person(name) {if (!(this instanceof Person)) {return new Person(name);}this.name = name;
}
const p = Person("Henry"); // 自動補 new
2. 方法重復創建(內存浪費)

問題:構造函數內定義方法會導致每個實例獨立一份方法。

function Person(name) {this.name = name;this.greet = function() {}; // 每個實例都有 greet 方法
}

解決:將方法定義在原型上。

Person.prototype.greet = function() {}; // 共享方法

六、總結

  • 對象創建方式:根據場景選擇字面量、構造函數、class?等。

  • 構造函數核心:結合?new?實現實例化,通過原型鏈共享方法。

  • new?的機制:創建對象、綁定原型、執行構造函數、返回對象。

  • 最佳實踐:方法定義在原型上,避免內存浪費;使用?class?提升代碼可讀性。


??

實例成員與靜態成員


一、實例成員(Instance Members)

1. 定義與特點
  • 定義:屬于實例對象的屬性和方法,每個實例獨立擁有。

  • 特點

    • 實例屬性:通過構造函數內的?this?定義,每個實例獨占內存。

    • 實例方法:定義在構造函數的?prototype?上,所有實例共享。

  • 示例

    function Person(name) {this.name = name; // 實例屬性(每個實例獨立)
    }// 實例方法(共享)
    Person.prototype.sayHello = function() {console.log(`Hello, I'm ${this.name}`);
    };const alice = new Person("Alice");
    alice.sayHello(); // "Hello, I'm Alice"
2. 內存模型
  • 實例屬性:每個對象在堆中獨立存儲。

  • 實例方法:存儲在原型對象(Person.prototype)中,所有實例通過原型鏈共享。


二、靜態成員(Static Members)

1. 定義與特點
  • 定義:屬于構造函數本身的屬性和方法,無需實例化即可訪問。

  • 特點

    • 通過構造函數直接調用(如?Array.isArray())。

    • 無法訪問實例成員(無?this?指向實例)。

  • 示例

    function Person() {}// 靜態屬性
    Person.species = "Homo sapiens";// 靜態方法
    Person.createAnonymous = function() {return new Person("Anonymous");
    };console.log(Person.species); // "Homo sapiens"
    const anon = Person.createAnonymous();
2. ES6?class?中的靜態成員
  • 使用?static?關鍵字定義:

    class Person {static species = "Homo sapiens"; // 靜態屬性static createAnonymous() {       // 靜態方法return new Person("Anonymous");}
    }

三、實例成員 vs 靜態成員

特性實例成員靜態成員
歸屬實例對象構造函數
內存占用屬性獨立,方法共享全局唯一
訪問方式instance.propertyConstructor.property
this?指向實例對象構造函數
適用場景對象狀態和行為工具方法、工廠函數、類配置

四、關鍵使用場景

1. 實例成員的典型應用
  • 描述對象狀態(如?person.name)。

  • 定義對象行為(如?person.sayHello())。

2. 靜態成員的典型應用
  • 工具函數:無需實例即可調用的功能(如?Math.abs())。

  • 工廠方法:創建特定類型的實例(如?Person.createAnonymous())。

  • 全局配置:類級別的常量或配置(如?Person.DEFAULT_AGE = 30)。


五、繼承與靜態成員

1. ES6?class?的靜態繼承
  • 子類自動繼承父類的靜態成員:

    class Employee extends Person {static role = "Developer";
    }
    console.log(Employee.species); // "Homo sapiens"(繼承自 Person)
2. ES5 手動實現靜態繼承
  • 需顯式復制靜態成員或設置原型鏈:

    function Person() {}
    Person.species = "Homo sapiens";function Employee() {}
    // 繼承實例方法
    Employee.prototype = Object.create(Person.prototype);
    // 繼承靜態成員
    Object.setPrototypeOf(Employee, Person);console.log(Employee.species); // "Homo sapiens"

六、常見問題與解決方案

1. 靜態方法中訪問實例成員
  • 問題:靜態方法無實例上下文,無法直接訪問實例屬性。

  • 解決:通過參數傳遞實例:

    Person.compareAge = function(person1, person2) {return person1.age - person2.age;
    };
2. 實例方法誤用?this?訪問靜態成員
  • 問題:實例方法中?this?指向實例,無法直接訪問靜態成員。

  • 解決:通過構造函數名訪問:

    Person.prototype.logSpecies = function() {console.log(Person.species); // 正確
    };

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

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

相關文章

AIDD-人工智能藥物設計-深度學習助力提高兒童低級別膠質瘤復發風險預測的準確性

深度學習助力提高兒童低級別膠質瘤復發風險預測的準確性 兒童低級別膠質瘤(pLGG)是一種常見于兒童患者中的腦腫瘤,盡管大多數時候被認為是良性腫瘤,但是它們仍然可能導致相關癥狀和并發癥的發生,包括但不限于頭疼、癲…

redis的數據類型(1)

https://redis.io/docs/latest/develop/data-types/strings/ 社區版支持: String,字符串 Hash,key-value格式 List,根據插入順序排序 Set,集合 Sorted set,有排序 Stream, Bitmap, …

Nacos配置中心使用

Nacos配置中心 Nacos除了可以做注冊中心,🔗Nacos下載和注冊中心教程,同樣可以做配置管理來使用。 一、統一配置管理 當微服務部署的實例越來越多,達到數十、數百時,逐個修改微服務配置就顯得十分的不方便,而且很容易出錯。我們…

OpenCV輪廓檢測全面解析:從基礎到高級應用

一、概述 輪廓檢測是計算機視覺中的基礎技術,用于識別和提取圖像中物體的邊界。與邊緣檢測不同,輪廓檢測更關注將邊緣像素連接成有意義的整體,形成封閉的邊界。 輪廓檢測的核心價值 - 物體識別:通過輪廓可以識別圖像中的獨立物體…

Jenkins學習(B站教程)

文章目錄 1.持續集成CI2.持續交付CD3.持續部署4.持續集成的操作流程5.jenkins簡介6.后續安裝部署,見視頻 bilibili視頻 Jenkins是一個開源的、提供友好操作界面的持續集成(CI)工具,起源于Hudson(Hudson是商用的),主要用…

ARM-UART

時鐘選擇PLCK,超時3ms自動發送,設置發送8位的緩沖區,且發送中斷 設置觸發深度,達到8字節將緩沖區數據發憷 中斷處理函數

Rust所有權詳解

文章目錄 Rust所有權所有權規則作用域 內存和分配移動與克隆棧空間堆空間 關于函數的所有權機制作為參數作為返回值 引用與租借垂懸引用 Rust所有權 C/C中我們對于堆內存通常需要自己手動管理,手動申請和釋放,即便有了智能指針,對于效率的影…

【在線OJ項目測試報告】

朋友們、伙計們,我們又見面了,本期來給大家帶來關于在線OJ項目的測試報告,如果看完之后對你有一定的啟發,那么請留下你的三連,祝大家心想事成! C 語 言 專 欄:C語言:從入門到精通 數…

【HFP】藍牙HFP應用層核心技術研究

免提配置文件(Hands-Free Profile, HFP)作為實現設備間音頻通信的關鍵協議,廣泛應用于車載系統、藍牙耳機等場景。本文將基于最新技術規范,深入剖析HFP應用層的功能要求、協議映射及編解碼器支持,為藍牙開發工程師提供詳盡的技術指南。 一、HFP應用層功能全景圖 HFP定義…

橫掃SQL面試——PV、UV問題

📊 橫掃SQL面試:UV/PV問題 🌟 什么是UV/PV? 在數據領域,UV(Unique Visitor,獨立訪客) 和 PV(Page View,頁面訪問量) 是最基礎也最重要的指標&…

【C++】第八節—string類(上)——詳解+代碼示例

hello,又見面了! 云邊有個稻草人-CSDN博客 C_云邊有個稻草人的博客-CSDN博客——C專欄(質量分高達97!) 菜鳥進化中。。。 目錄 一、為什么要學習string類? 1.1 C語言中的字符串 1.2 面試題(暫不做講解) …

如何判斷JVM中類和其他類是不是同一個類

如何判斷JVM中的類是否為同一個類 在Java虛擬機(JVM)中,判斷兩個類是否相同需要同時滿足以下三個條件: 1. 類全限定名必須相同 包括包名類名的完整路徑必須完全一致例如:java.lang.String和com.example.String被視為不同類 2. 加載該類的…

ifconfig 使用詳解

目錄 一、基本語法二、常見用途及示例1. 查看所有網絡接口信息2. 啟用/禁用網絡接口3. 配置 IP 地址和子網掩碼4. 修改 MAC 地址5. 啟用混雜模式(Promiscuous Mode)6. 設置 MTU(最大傳輸單元) 三、其他選項四、常見問題1. 新系統中…

1. 標準庫的強依賴(核心原因)

1. 標準庫的強依賴(核心原因) 容器操作(如 std::vector 擴容) 當標準庫容器(如 std::vector)需要重新分配內存時,它會嘗試移動現有元素到新內存,而非拷貝(為了性能&…

【MySQL】常用SQL--持續更新ing

一、配置信息類 1.查看版本 select version; 或 select version(); 2.查看配置 show global variables where variable_name in (basedir,binlog_format,datadir,expire_logs_days,innodb_buffer_pool_size,innodb_log_buffer_size,innodb_log_file_size,innodb_log_files_i…

Day82 | 靈神 | 快慢指針 重排鏈表

Day82 | 靈神 | 快慢指針 重排鏈表 143.重排鏈表 143. 重排鏈表 - 力扣(LeetCode) 思路: 筆者直接給跪了,這個難度真是mid嗎 直接去看靈神的視頻 環形鏈表II【基礎算法精講 07】_嗶哩嗶哩_bilibili 1.簡單來說就是&#xf…

常見的微信個人號二次開發功能

一、常見開發功能 1. 好友管理 好友列表維護 添加/刪除好友 修改好友信息(備注、標簽等) 分組管理 創建/編輯/刪除標簽 好友分類與篩選 2. 消息管理 信息發送 支持多類型內容:文本、圖片、視頻、文件、小程序、名片、URL鏈接等 附加功…

Android打包及上架應用市場問題處理

一、Gradle 配置參數含義: compileSdkVersion: 29 表示項目編譯時使用的 Android SDK 版本為 API 29(Android 10),僅影響編譯階段的行為(如代碼語法檢查、資源處理等),不直接影響運行時兼容性。…

Docker 從入門到進階 (Win 環境) + Docker 常用命令

目錄 引言 一、準備工作 1.1 系統要求 1.2 啟用虛擬化 二、安裝Docker 2.1 安裝WSL 2 2.2 安裝Docker Desktop 2.3檢查是否安裝成功 三、配置Docker 3.1 打開Docker配置中心 四、下載和管理Docker鏡像 4.1 拉取鏡像 4.2 查看已下載的鏡像 4.3 運行容器 4.4 查看正…

計算機視覺5——運動估計和光流估計

一、運動估計 (一)運動場(Motion Field) 定義與物理意義 運動場是三維場景中物體或相機運動在二維圖像平面上的投影,表現為圖像中每個像素點的運動速度矢量。其本質是場景點三維運動(平移、旋轉、縮放等&a…