JS創(chuàng)建對象的六種方式
1.對象字面量(Object Literal)
用法: 直接通過{}定義對象,是最簡單的方式;
原理: 直接分配內(nèi)存創(chuàng)建一個普通對象,繼承object.prototype;
- 直接內(nèi)存分配: 當(dāng)使用{}定義對象時,js引擎會直接在堆內(nèi)存中分配一個普通對象。
- 隱藏原型繼承: 該對象的[[Prototype]](即 proto) 會自動指向 Object.prototype, 繼承原始對象默認(rèn)方法 (如:toString).
- 屬性初始化: 字面量中的屬性和方法會直接掛載到對象自身,而非原型鏈。
例子:
const person { name: '小明', age: 25, greet() { console.log(`hi , i'm ${this.name}`) } } person.greet() //hi ,i'm 小明
const obj = {key:“value”}; //等價于: const obj = new Object(); //隱式調(diào)用 Object 構(gòu)造函數(shù) obj.key = "value";
特點:
- 適合創(chuàng)建單例對象或一次性對象;
- 所有屬性方法均為實例自身成員,無法共享
2.構(gòu)造函數(shù)(constructor function)
用法:通過 new 關(guān)鍵字調(diào)用構(gòu)造函數(shù)創(chuàng)建對象
原理: new 操作
- 1.創(chuàng)建空對象: 在內(nèi)存中創(chuàng)建一個新對象 {}
- 2.綁定原型:將新對象的[[Prototype]] 即原型鏈, 指向構(gòu)造函數(shù)的prototype屬性
- 3.執(zhí)行構(gòu)造函數(shù):將構(gòu)造函數(shù)內(nèi)的this指向新對象,執(zhí)行構(gòu)造函數(shù)代碼(初始化屬性)
- 4.返回對象: 若構(gòu)造函數(shù)未顯示返回其他對象,則返回新對象;
例子:
function person(name, age){ // this = {}; (隱式操作) // this.__proto__ = person.prototype; (隱式操作) this.name = name; this.age = age; this.greet = function(){ console.log(`hi, i'm ${this.name}`) } // return this; (隱式操作) } const xiaoming = new person('小明', 25); xiaoming.greet(); //hi, i'm 小明 //原型鏈結(jié)構(gòu): xiaoming.__proto__ -> person.prototype -> Object.prototype -> null;
缺點:每個實例的方法都是獨立的,浪費內(nèi)存(可以優(yōu)化共享原型方法);
- 若方法定義在構(gòu)造函數(shù)內(nèi)部,每個實例會有獨立的方法副本(浪費內(nèi)存);
- 若方法定義在person.prototype上,所有實例共享同一方法(推薦做法)
3. Object.create()
用法:基于現(xiàn)有對象作為原型創(chuàng)建新對象。
原理:創(chuàng)建一個新對象,并將其Prototype 指向傳入的對象;
- 顯式原型繼承:直接創(chuàng)建一個新對象,并手動指定其[[Prototype]] 即:原型鏈 __ proto __
- 參數(shù)處理: 1.若傳入null, 新對象的[[Prototype]]為null (無原型鏈); 2.若傳入對象proto, 新對象繼承proto的屬性和方法;
例子:
const prototypeObj = { greet(){ console.log(`hi, i'm ${this.name}`) } } const person = Object.create(prototypeObj); person.name = "小明"; person.age = 10; person.greet(); //hi , i'm 小明
擴(kuò)展:可創(chuàng)建無原型的對象(Object.create(null)),適合純粹的數(shù)據(jù)存儲;
4.工廠函數(shù)(Factory Function)
用法: 封裝對象創(chuàng)建邏輯的函數(shù),直接返回新對象;
原理:手動創(chuàng)建對象并返回,不依賴 new 或原型鏈;
- 封裝對象創(chuàng)建: 通過普通函數(shù)返回新對象,不依賴new或者原型鏈。
- 獨立實例: 每次調(diào)用工廠函數(shù)都會產(chǎn)生新的對象,所有屬性和方法均為實例自身成員。
例子:
function createPeason(name,age){ const obj = {}; //顯示創(chuàng)建對象 obj.name = name; obj.age = age; obj.greet = function(){} //方法不共享 return obj; } const xiaoming = createPeason('小明',10); xiaoming.greet(); //hi, i'm 小明;
特點:避免 new 的使用,但方法無法共享(每個實例的方法獨立)。
對比構(gòu)造函數(shù):
- 優(yōu)勢: 更直觀,避免new 的依賴。
- 劣勢: 方法無法共享,內(nèi)存效率低。 (因為是閉包?。?/li>
5.ES6 class 語法
用法:使用clase關(guān)鍵字定義類,通過new實例化;
原理:本質(zhì)是構(gòu)造函數(shù)的語法糖(構(gòu)造函數(shù)另一種寫法),基于原型鏈實現(xiàn)繼承。
- 方法掛載: 類中定義的方法會自動添加到prototype對象上,實現(xiàn)共享;
- 繼承機制: extends 關(guān)鍵字通過修改原型鏈實現(xiàn)繼承(子類的prototype 指向父類實例)
例子:
class Person { construtor(name,age){ this.name = name; this.age = age; } greet(){ console.log(`hi, i'm ${this.name}`) } } const xiaoming = new Person('小明',10); xiaoming.greet(); // hi, i'm 小明; //原型鏈結(jié)構(gòu): xiaoming.__proto__ -> Person.prototype -> Object.prototyle -> null;
優(yōu)點: 語法更清晰,支持繼承(extends)和靜態(tài)方法(static)
6.單例模式(Singleton)
用法:確保一個類只有一個實例;
原理:通過閉包或模塊化限制實例化次數(shù)
- 閉包封裝: 通過立即執(zhí)行函數(shù)(iife)和閉包保存唯一實例的引用。
- 惰性初始化: 在首次調(diào)用時創(chuàng)建實例,后續(xù)調(diào)用直接返回已存在的實例;
例子:
const singleton - (function(){ let instance; function createInstance() { return { id: Math.random() }; } return { getInstance(){ if(!instance) instance = createInstance(); return instance; } } })(); const obj1 = singleton.getInstance(); const obj2 = singleton.getInstance(); console.log(obj1 === obj2); //true
匯總 - 總結(jié)對比
方式 | 特點 | 適用場景 |
---|---|---|
對象字面量 | 簡單直接,適合一次性對象 | 簡單數(shù)據(jù)存儲、配置項 |
構(gòu)造函數(shù) | 可復(fù)用,但方法定義在原型上 節(jié)省內(nèi)存 | 需要多個相似實例 |
Object.create() | 靈活控制原型鏈,可創(chuàng)建無原型的對象 | 原型繼承、純凈對象 |
工廠函數(shù) | 避免 new, 但方法無法共享 | 簡單對象生活 |
class | 語法清晰,支持繼承 | 面向?qū)ο箝_發(fā) |
單例模式 | 全局唯一實例 | 全局狀態(tài)管理 |
選擇建議:
- 簡單對象: 優(yōu)先用對象字面量或者工廠函數(shù)。
- 復(fù)用和繼承: 使用class或構(gòu)造函數(shù)。
- 原型控制: 使用Object.create()。
- 全局唯一: 單例模式。
以上就是JS創(chuàng)建對象的六種方式的詳細(xì)內(nèi)容,更多關(guān)于JS創(chuàng)建對象的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
artdialog的圖片/標(biāo)題以及關(guān)閉按鈕不顯示的解決方法
正如標(biāo)題所言不顯示的原因是因其它css樣式文件中包含div{ overflow:hidden; }引起的artdialog的圖片以及關(guān)閉按鈕不顯示,具體的解決方法如下,感興趣的朋友可以參考下哈2013-06-06深入理解Canvas模糊問題產(chǎn)生的原因與解決辦法
我們在使用Canvas進(jìn)行繪圖時,經(jīng)常會出現(xiàn)繪制的文字或者圖片比較模糊,這篇文章我們就來討論一下Canvas模糊問題產(chǎn)生的原因與解決辦法吧2024-04-04JavaScript蒙板(model)功能的簡單實現(xiàn)代碼
本文給大家介紹JavaScript蒙板(model)功能的簡單實現(xiàn)代碼,創(chuàng)建一個蒙板, 設(shè)置蒙板的堆疊順序保證能將其它元素蓋住,感興趣的朋友可以參考下實現(xiàn)代碼2016-08-08