JS創(chuàng)建對(duì)象常用設(shè)計(jì)模式工廠構(gòu)造函數(shù)及原型
引言
很多工友們都說:設(shè)計(jì)模式根本用不到,然而它其實(shí)時(shí)刻就在我們身邊,像王國(guó)維所說:眾里尋他千百度,驀然回首,那人正在燈火闌珊處。
工廠模式
什么是工廠模式?其實(shí)就字面意思,在現(xiàn)實(shí)社會(huì)生活中,市場(chǎng)通過不同工廠加工成不同的產(chǎn)品。
轉(zhuǎn)化成 JS 代碼就是這樣的:
// 汽車工廠 function carFactory(brand, price, district) { let o = new Object(); o.brand= brand; o.price= price; o.district= district; o.performance= function() { console.log(this.brand); }; return o; } // 生產(chǎn)汽車 let car1 = carFactory("Benz", 50, "china"); let car2= carFactory("Honda", 30, "usa");
// 糖果工廠 function candyFactory(name, size, color) { let o = new Object(); o.name= name; o.size= size; o.color= color; o.performance= function() { console.log(this.name); }; return o; } // 生產(chǎn)糖果 let candy1= candyFactory("Oreo", "small", "white"); let candy2= candyFactory("quduoduo", "middle", "black");
有汽車工廠,糖果工廠等等,我們通過工廠函數(shù),創(chuàng)建了特定對(duì)象。
工廠模式是一種眾所周知的設(shè)計(jì)模式,廣泛應(yīng)用于軟件工程領(lǐng)域,用于抽象創(chuàng)建特定對(duì)象的過程。
構(gòu)造函數(shù)模式
構(gòu)造函數(shù)是用于創(chuàng)建特定類型對(duì)象的,可以自定義構(gòu)造函數(shù),以函數(shù)的形式為自己的對(duì)象類型定義屬性和方法。
比如前面的例子,就可以該寫為:
// 構(gòu)造汽車的構(gòu)造函數(shù) function Car(brand, price, district) { this.brand= brand; this.price= price; this.district= district; this.performance= function() { console.log(this.brand); }; } // 構(gòu)造汽車 let car1 = new Car("Benz", 50, "china"); let car2= new Car("Honda", 30, "usa");
與工廠模式的區(qū)別是,構(gòu)造函數(shù)模式:
- 沒有顯式地創(chuàng)建對(duì)象;
- 屬性和方法直接賦值給了 this;
- 沒有 return;
構(gòu)造函數(shù)首字母通常是大寫;
這里涉及到一個(gè)重要的考點(diǎn):即使用 new 會(huì)發(fā)生什么?
官方解答:
(1) 在內(nèi)存中創(chuàng)建一個(gè)新對(duì)象。 (2) 這個(gè)新對(duì)象內(nèi)部的[[Prototype]](隱式原型)特性被賦值為構(gòu)造函數(shù)的 prototype (顯示原型)屬性。 (3) 構(gòu)造函數(shù)內(nèi)部的 this 被賦值為這個(gè)新對(duì)象(即 this 指向新對(duì)象)。 (4) 執(zhí)行構(gòu)造函數(shù)內(nèi)部的代碼(給新對(duì)象添加屬性)。 (5) 如果構(gòu)造函數(shù)返回非空對(duì)象,則返回該對(duì)象;否則,返回剛創(chuàng)建的新對(duì)象。
這個(gè),就是“原型鏈”的構(gòu)造過程??!
car1.__proto__===Car.prototype // true car1 instanceof Car // true
- 構(gòu)造函數(shù)的問題
構(gòu)造函數(shù)的主要問題在于,其定義的方法會(huì)在每個(gè)實(shí)例上都創(chuàng)建一遍。
什么意思?用代碼來解釋:
// 構(gòu)造汽車的構(gòu)造函數(shù) function Car(brand, price, district) { this.brand= brand; this.price= price; this.district= district; this.performance= function() { }; } // 構(gòu)造汽車 let car1 = new Car("Benz", 50, "china"); let car2= new Car("Honda", 30, "usa"); car1.performance == car2.performance // false
即使是同樣的方法,也不相等,因?yàn)槊看螆?zhí)行 new 的時(shí)候,實(shí)例的方法都是重新創(chuàng)建的;
原型模式
原型模式可以解決構(gòu)造函數(shù)模式“重復(fù)創(chuàng)建方法”的問題。
// 原型創(chuàng)建 function Car(brand, price, district) { Car.prototype.brand= brand; Car.prototype.price= price; Car.prototype.district= district; Car.prototype.performance= function() { }; } let car1 = new Car("Benz", 50, "china"); let car2= new Car("Honda", 30, "usa"); car1.performance === car2.performance // true
這里不妨再重溫一下原型鏈的指向關(guān)系:
car1.__proto__===Car.prototype // true Car.__proto__===Function.prototype // true Function.prototype.__proto__===Object.prototype //true Car.prototype.__proto__===Object.prototype //true Object.prototype.__proto__===null // true
原型模式弱化了向構(gòu)造函數(shù)傳遞初始化參數(shù)的能力,會(huì)導(dǎo)致所有實(shí)例默認(rèn)都取得相同的屬性值。
function Person() {} Person.prototype = { constructor: Person, friends: "A", sayName() { } }; let person1 = new Person(); let person2 = new Person(); person1.friends="B"; person1.friends // 'B' person2.friends // 'A'
function PersonArr() {} PersonArr.prototype = { constructor: PersonArr, friends:["A"], sayName() { } }; let person1 = new PersonArr(); let person2 = new PersonArr(); person1.friends.push("B"); person1.friends // ["A","B"] person2.friends // ["A","B"]
原型上的所有屬性是在實(shí)例間共享的,這對(duì)函數(shù)來說比較合適。對(duì)原始值的屬性 也還好,但對(duì)于引用值的屬性,則會(huì)產(chǎn)生混亂??!
結(jié)語(yǔ)
工廠模式、構(gòu)造函數(shù)模式、原型模式,這三者沒有誰(shuí)好誰(shuí)壞,使用時(shí),更多的是講究一個(gè) —— 適合!只有清楚它們的原理,才能游刃有余。
更多關(guān)于JS創(chuàng)建對(duì)象設(shè)計(jì)模式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript 對(duì)象創(chuàng)建的3種方法
這篇文章主要給大家分享的時(shí)JavaScript 對(duì)象創(chuàng)建的3種方法,在 JavaScript中,對(duì)象是一組有屬性名和屬性值組成的無序集合,對(duì)象的創(chuàng)建可以通過對(duì)象字面量、new 關(guān)鍵字 和Object.create()函數(shù)來創(chuàng)建。2021-11-11JavaScript高級(jí)程序設(shè)計(jì)之變量與作用域
這篇文章主要介紹了JavaScript高級(jí)程序設(shè)計(jì)之變量與作用域,文章主要通過描述原始值與引用值、instanceof、作用域展開具體內(nèi)容,需要的朋友可以參考一下2021-11-11微信小程序 Windows2008 R2服務(wù)器配置TLS1.2方法
微信小程序免費(fèi)SSL證書https、TLS版本問題的解決方案《二十四》request:fail錯(cuò)誤(含https解決方案)(真機(jī)預(yù)覽問題把下面的代碼復(fù)制到PowerShell里運(yùn)行一下,然后重啟服務(wù)器。# Enables TLS 1.2 on ...,需要的朋友可以參考下2016-12-12JS前端以輕量fabric.js實(shí)現(xiàn)示例理解canvas
這篇文章主要為大家介紹了JS前端以輕量fabric.js實(shí)現(xiàn)示例理解canvas可視化,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08uniapp五分鐘實(shí)現(xiàn)刷抖音小程序教程示例
這篇文章主要為大家介紹了uniapp五分鐘實(shí)現(xiàn)刷抖音小程序教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03JavaScript+HTML實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)
這篇文章主要介紹了JavaScript實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)js的小伙伴們有一定的幫助,需要的朋友可以參考下2021-04-04