本篇文章給大家分享的是有關(guān)JavaScript中有哪些常見(jiàn)的構(gòu)造模式,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。
創(chuàng)新互聯(lián)建站2013年至今,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元響水做網(wǎng)站,已為上家服務(wù),為響水各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:13518219792
1.工廠模式
沒(méi)有解決對(duì)象識(shí)別的問(wèn)題。因?yàn)楹瘮?shù)內(nèi)部使用了new Object來(lái)創(chuàng)建對(duì)象
function Factory(name,age) { var o=new Object(); o.name=name; o.age=age; o.what=what;//用函數(shù)引用的方式消除重復(fù)創(chuàng)建相同函數(shù)的弊端,節(jié)省資源.函數(shù)引用可以修改this的指向,函數(shù)調(diào)用不可以! return o; } what=funciton() { alert(this.name+this.age); } var o=Factory("12",12); o.what();//what中的this指向o對(duì)象
這時(shí)候的constructor是Object,同時(shí)所有通過(guò)工廠模式返回的對(duì)象都是Object類型,所以instanceof
操作符沒(méi)有意義
console.log(o.constructor); //打印function Object() { [native code] } console.log(o instanceof Object); //而且這時(shí)候所有的對(duì)象都是Object類型的
2.構(gòu)造函數(shù)模式
function Person(name,age) { this.name=name; this.age=age; this.sayName=function(){ alert(this.name);}//相當(dāng)于this.sayName=new Function("alert(this.name)") } var p1=new Person("xx",12); var p2=new Person("yy",13); alert(p1.sayName==p2.sayName)//內(nèi)存地址不一樣!返回false
構(gòu)造函數(shù)相比工廠模式的優(yōu)點(diǎn)在于能夠正確的返回對(duì)象的類型,instanceof
返回正確的結(jié)果。缺點(diǎn)在于如果向上面那樣,那么在每一個(gè)對(duì)象上面都要有一個(gè)sayName方法,而且這些sayName方法不是同一個(gè)Function實(shí)例,因?yàn)镋CMAScript中函數(shù)是對(duì)象,因此每定義一個(gè)函數(shù),也就是實(shí)例化了一個(gè)對(duì)象!
對(duì)上面的方法進(jìn)行優(yōu)化:
function Person(name,age) { this.name=name; this.age=age; this.sayName=sayName;//函數(shù)引用的方法,共享了同一個(gè)sayName,p1,p2的內(nèi)存地址一樣,p1.sayName==p2.sayName返回true } function sayName() { alert(this.name); }
缺點(diǎn):全局函數(shù)sayName只能被某個(gè)對(duì)象調(diào)用p1.sayName
,讓全局函數(shù)名不副實(shí);如果對(duì)象要定義很多方法,那么就要定義很多的全局函數(shù),所以自定義的引用類型沒(méi)有封裝性可言
3.原型模式
(1)無(wú)法通過(guò)構(gòu)造函數(shù)參數(shù)向原型屬性動(dòng)態(tài)傳值,后果就是:沒(méi)有個(gè)性,改變?cè)蛯傩缘闹担械膶?shí)例都會(huì)受到干擾!
(2)當(dāng)原型屬性的是引用類型的時(shí)候,如果在一個(gè)對(duì)象實(shí)例上修改屬性,將會(huì)影響所有實(shí)例!
總之一句話:牽一發(fā)而動(dòng)全身(包括屬性和引用類型的值)是原型模式的特點(diǎn)。但是相比于構(gòu)造函數(shù)類型,原型類型滿足
person1.sayName===person2.sayName//兩者的引用是一樣的
4.構(gòu)造函數(shù)原型模式
用構(gòu)造函數(shù)定義個(gè)性,用原型模式定義共性
function Person(name,age) { this.name=name; this.age=age; this.friends=['liangklfang','qinliang']; } //用原型定義共性 Person.prototype={ constructor:Person, sayName:function() { console.log(this.name); } } var person1=new Person('liangklfang',"12"); var person2=new Person('liangklf',"14"); console.log(person1.sayName===person2.sayName); //共性是函數(shù),打印true console.log(person1.friends===person2.friends); //friends是個(gè)性,打印false
也可以對(duì)構(gòu)造函數(shù)原型模式進(jìn)行優(yōu)化,就是常說(shuō)的動(dòng)態(tài)原型模式
function Book(title,page) { this.title=title; this.page=page; if(typeof Book.isLock=="undefined") //第一次的時(shí)候,Book.isLock是undefined,給原型綁定函數(shù),以后就不需要了,他相比于構(gòu)造函數(shù)原型模式的優(yōu)點(diǎn)在于把所有的邏輯全部封裝到構(gòu)造函數(shù)里面! { alert("Enter!"); Book.prototype.what=function() { alert(this.title+this.pages); } Book.isLock=true; } } //下面的兩次調(diào)用alert("Enter!")只會(huì)調(diào)用因此i,因?yàn)榈谝淮我呀?jīng)通過(guò)Book.isLock設(shè)置為true了!相當(dāng)于靜態(tài)方法!; var b1=new Book("me",12); b1.what(); var b2=new Book("he",13); b2.what();
也可以在this
中直接檢測(cè),而不用給函數(shù)對(duì)象一個(gè)屬性
function Book(title,page) { this.title=title; this.page=page; if(typeof this.sayName!='function') //第二次構(gòu)造對(duì)象的時(shí)候會(huì)在原型中查找到sayName! { Book.prototype.sayName=function() { console.log(this.title); } } }
5.寄生構(gòu)造函數(shù)模式
除了使用new
操作符以外,和工廠設(shè)計(jì)模式是一模一樣的!可以在特殊的情況下為對(duì)象創(chuàng)建構(gòu)造函數(shù),例如想用構(gòu)造函數(shù)方式創(chuàng)建一個(gè)具有額外方法的特殊數(shù)組,因?yàn)椴荒苤苯有薷腁rray的構(gòu)造函數(shù),因此可以用這個(gè)模式!
function SpecialArray() { var value=new Array(); value.push.apply(value,arguments); value.toPipedString=function() { return this.join("|"); } return value; }
總之,寄生構(gòu)造函數(shù)的特點(diǎn)就是:有點(diǎn)像java中的裝飾模式!把原來(lái)的對(duì)象進(jìn)行裝飾,同時(shí)返回裝飾后的對(duì)象!這里就是把Array對(duì)象進(jìn)行了裝飾!添加了toPipe的String
方法。缺點(diǎn)就是不能依賴instanceof
操作符確定對(duì)象類型了,因?yàn)楹筒辉侔b類里面創(chuàng)建的對(duì)象是一模一樣的!
6. 穩(wěn)妥構(gòu)造函數(shù)模式
特點(diǎn):沒(méi)有公共屬性,而且其方法也不引用this的對(duì)象,instanceof
失效。和寄生構(gòu)造函數(shù)的不同在于不使用new
來(lái)構(gòu)造函數(shù),同時(shí)實(shí)例方法不引用this
。實(shí)際是閉包
function Person(name,age,job) { var o=new Object(); o.sayName=funciton(){alert(name)}//這里實(shí)例方法沒(méi)有引用this,除了sayName不會(huì)有方法訪問(wèn)傳入到構(gòu)造函數(shù)中的原始數(shù)據(jù)! return o; } var friend=Person("xx",12,"teacher"); friend.name="female";//即使可以為這個(gè)對(duì)象修改了屬性name friend.sayName();//不會(huì)被修改,依然彈出xx。不是female。但是,如果把上面的修改成:o.sayName=function(){alert(this.name)}//那么就會(huì)彈出female,也就是friend.name被修改成功了,如果沒(méi)有this,那么name的值一直引用的是原來(lái)的參數(shù)值!
以上就是JavaScript中有哪些常見(jiàn)的構(gòu)造模式,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。