JS創(chuàng)建對象的十種方式總結
前言
面向對象是一種重要的編程范式,如何靈活的創(chuàng)建對象,是對編程基本功的考驗,本來我們來探討創(chuàng)建對象的十種方式。我將這十種分為new Object
、構造函數(shù)與原型對象、其他三個大類。
new Object
這三種本質都是new Object
,他們無法根據(jù)對象的原型對象準確判斷對象的類型,因為原型對象上都是Object。console.log(obj.__proto__===Object.prototype); // true
new Object
const obj = new Object({name: 'wayne',age: 18})
字面量方式
const obj = {name: 'wayne',age: 18}
工廠函數(shù)方式
function createPerson(name, age) { return {name,age,} } const obj = createPerson('wayne', 18)
構造函數(shù)與原型對象
這四種是對構造函數(shù)與原型對象創(chuàng)建對象上的細化。
構造函數(shù)方式
如果構造函數(shù)中包含的方法,則會重復創(chuàng)建,造成內存的浪費(只適合放屬性不適合方法)
function Person(name, age) { this.name = name this.age = age this.getInfo = function() { console.log(this.name, this.age) } } const obj = new Person('wayne', 18)
原型對象方式
合放方法:將共同的方法放到原型當中可以避免重新創(chuàng)建相同功能的方法,減少了內存的使用。 不適合放屬性:原因有三條
- new初始化新的屬性時候不方便,
- 修改起來不方便
p1.__proto__.name = 'jack'
- 在原型對象的屬性會在所有的對象上共享,導致新new出來出現(xiàn)問題
function Person() {} Person.prototype.name = "wayne" Person.prototype.age = 10 Person.prototype.getInfo = function() { console.log(this.name, this.age) } const p1 = new Person() // 這里使用的是原型上的屬性 p1.getInfo() // wayne 10 // 修改原型上的屬性 p1.__proto__.name = 'jack' p1.__proto__.age = 18 // 這里使用的是原型上的屬性 p1.getInfo() // jack 18 const p2 = new Person() // 修改過的屬性 p2.getInfo() // jack 18
混合模式
這是我們常見的方式,將屬性放在構造函數(shù),方法放在原型上。但這種方式不太符合面向對象封裝的思想。
function Person(name, age) { this.name = name this.age = age } Person.prototype.getInfo = function() { console.log(this.name, this.age) } const p1 = new Person(name, age)
動態(tài)混合
其實就是混合模式的改進,這種方式的缺點是語義不符,其實只有第一個對象創(chuàng)建時才會走 if 判斷
function Person(name, age) { this.name = name this.age = age if (Person.prototype.getInfo === "undefined") { Person.prototype.getInfo = function() { console.log(this.name, this.age) } } } // 第一次調用時會給 Person.prototype 添加 getInfo 方法 const p1 = new Person("wayne", 18) const p2 = new Person("jack", 15)
寄生構造函數(shù)
和動態(tài)混合一樣,但通過函數(shù)里調用其他構造函數(shù)
function Person(name, age) { this.name = name this.age = age if (Person.prototype.getInfo === "undefined") { Person.prototype.getInfo = function() { console.log(this.name, this.age) } } } function func(name, age) { const p = new Person(name, age) return p } const p1 = func("wayne", 18)
其他
class
使用ES6語法糖class創(chuàng)建對象,其實class的本質就是function。
class Person { constructor(name, age) { this.name = name this.age = age } getInfo() { console.log(this.name, this.age) } } const p1 = new Person("wayne", 18) // class的本質是function console.log(typeof Person); //function
閉包
利用閉包的特性,也可以實現(xiàn)創(chuàng)建對象。優(yōu)點:不用this 和 new;缺點:容易造成內存泄漏。
function Person(name, age) { return { getName() { return name }, getAge: function() { return age } } } const p1 = Person("wayne", 18) console.log(p1.getName()) // wayne console.log(p1.getAge()) // 18
總結
new Object的三種
new Object
:new Object({name: 'wayne',age: 18})
- 字面量創(chuàng)建:
{name: 'wayne',age: 18}
- 工廠函數(shù)方式:
function createPerson(name, age) {return {name,age,}}
構造函數(shù)與原型對象四種
- 構造函數(shù)方式:適合屬性
- 原型對象方式:適合方法
- 混合方式:常見的方式,將屬性放在構造函數(shù),方法放在原型上。
- 動態(tài)混合:使用if判斷是否掛載方法
- 寄生構造函數(shù):通過函數(shù)里調用其他構造函數(shù)
其他兩種
- class,ES6語法糖,本質為function
- 閉包:優(yōu)點:不用this 和 new;缺點:容易造成內存泄漏。
以上就是JS創(chuàng)建對象的十種方式總結的詳細內容,更多關于JS創(chuàng)建對象的資料請關注腳本之家其它相關文章!
相關文章
JavaScript使用?for...in?、?for...of?或者?forEach()?遍歷元素的示例
for...in?、?for...of?和?forEach?都是用于循環(huán)遍歷集合元素的方法,但它們之間有一些重要的區(qū)別,本文通過實例代碼介紹JavaScript使用?for...in?、?for...of?或者?forEach()?遍歷元素的相關知識,感興趣的朋友一起看看吧2023-09-09用javascript實現(xiàn)的激活輸入框后隱藏初始內容
用javascript實現(xiàn)的激活輸入框后隱藏初始內容...2007-06-06