為什么要使用工廠模式和構(gòu)造函數(shù)方式創(chuàng)建對(duì)象?
雖然Object構(gòu)造函數(shù)(var obj = new Object();)或者字面量(var person={})可以創(chuàng)建單個(gè)對(duì)象肩祥,但是贮尖,他有一個(gè)明顯的缺點(diǎn)磁浇,那就是:重復(fù)造輪子,產(chǎn)生大量的重復(fù)性代碼窥摄,為了解決這個(gè)問(wèn)題,我們就開(kāi)始使用工廠模式和構(gòu)造函數(shù)模式。
什么是工廠模式 它有什么優(yōu)缺點(diǎn)?
顧名思義畦娄,工廠模式就是像工廠一樣來(lái)創(chuàng)建對(duì)象谐算。但這樣的解釋似乎有點(diǎn)欠妥熟尉,高大上一點(diǎn),工廠模式其實(shí)是軟件領(lǐng)域中一種廣為人知的一種設(shè)計(jì)模式洲脂,這種模式抽象了創(chuàng)建具體對(duì)象的過(guò)程斤儿。開(kāi)發(fā)人員發(fā)明了一種函數(shù),用函數(shù)來(lái)大量創(chuàng)建對(duì)象的方法恐锦;
下面是工廠模式創(chuàng)建對(duì)象的方法:
<pre>
<script>
function creatPerson(name,age,sex){
// var person = {};
// person.name = name;
// person.age = age;
// person.sex = sex;
// return person;
return{
name:name,
age:age,
sex:sex
}
}
var person1 = creatPerson("李四",18,"男")
var person2 = creatPerson("李四z",28,"男")
var person3 = creatPerson("李四zzz",30,"男")
console.log(person1);
console.log(person2);
console.log(person3);
</script>
</pre>
雖然工廠模式可以創(chuàng)建多個(gè)相似的對(duì)象往果,但是卻沒(méi)有解決對(duì)象的識(shí)別問(wèn)題(不知道這個(gè)對(duì)象的類(lèi)型)。
什么是構(gòu)造函數(shù)模式一铅,它和工廠模式比較有哪些好處陕贮?它自身又有那些缺點(diǎn)?
1.實(shí)例如下:
<pre>
<script>
function Person(name,age){
this.name = name;
this.age = age;
}
var p = new Person("張三","10s歲");
var p2 = new Person("李四","16歲");
console.log(p);
console.log(p2);
// console.log(p instanceof Object);
</script>
</pre>
這個(gè)例子中潘飘,Person()函數(shù)取代了person()函數(shù)肮之;睜大你的眼睛,構(gòu)造函數(shù)創(chuàng)建對(duì)象的函數(shù)名Person()明顯是開(kāi)頭大寫(xiě)卜录,這是構(gòu)造函數(shù)的慣例戈擒,為了區(qū)分和普通函數(shù)的區(qū)別,因?yàn)闃?gòu)造函數(shù)也是函數(shù)艰毒,只不過(guò)可以創(chuàng)建對(duì)象而已筐高。
要?jiǎng)?chuàng)建Person()的新實(shí)例,必須使用new现喳,即和使用var person1 = new Person()差不多凯傲,實(shí)際上會(huì)經(jīng)歷一些步驟:
- 創(chuàng)建一個(gè)新的對(duì)象;
- 將構(gòu)造函數(shù)作用域賦給新的對(duì)象(即this指向新對(duì)象)嗦篱;
- 執(zhí)行構(gòu)造函數(shù)里面的代碼冰单;
- 返回新的對(duì)象。
構(gòu)造函數(shù)和普通函數(shù)的區(qū)別在哪灸促?
1.構(gòu)造函數(shù)和普通函數(shù)唯一的區(qū)別是他們的調(diào)用方式不同诫欠。
2.任何函數(shù)只要通過(guò)new來(lái)調(diào)用涵卵,那它就可以作為構(gòu)造函數(shù),而任何函數(shù)荒叼,如果不通過(guò)new操作符來(lái)調(diào)用轿偎,他就是普通的函數(shù)。
實(shí)例如下:
<pre>
//當(dāng)做構(gòu)造函數(shù)來(lái)使用
var person1 = new CreatePerson('張三',18,'男');
person1.sex(); //'男'
//構(gòu)造函數(shù)當(dāng)做普通函數(shù)使用
CreatePerson('張三',18,'男')
window.sex();//'男'
</pre>
構(gòu)造函數(shù)有哪些不足之處?
我們可以參照上面的構(gòu)造函數(shù)的第一個(gè)實(shí)例被廓,可以得出這種方式創(chuàng)建函數(shù)實(shí)例創(chuàng)建的對(duì)象都包含一個(gè)不同的Function實(shí)例坏晦,所以,不同實(shí)例上的同名函數(shù)是不相等的嫁乘,證明如下:
<pre>console.log(person1.sex == person2.sex);//false</pre>
2.因此以上的寫(xiě)法可以這樣簡(jiǎn)化:
<pre>function CreatePerson(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
function sexes(){
console.log(this.sex);
}
var person1 = new CreatePerson('張三',18,'男');
var person2 = new CreatePerson('李四',18,'男')</pre>
這個(gè)時(shí)候的person1.sex和person2.sex就是相等的.
我們把函數(shù)放在構(gòu)造函數(shù)的外面作為全局函數(shù)昆婿,因此person1和person2對(duì)象就共享了在全局作用域中定義的同一個(gè)sexes函數(shù)。但是問(wèn)題又來(lái)了:在全局作用域中定義的函數(shù)實(shí)際上只能被某個(gè)對(duì)象調(diào)用蜓斧,這讓該全局作用域有點(diǎn)名不副實(shí)仓蛆。更讓然無(wú)法接受的是:如果對(duì)象需要定義很多方法,那么就要定義很多個(gè)全局函數(shù)挎春,那么我們這個(gè)自定義的引用類(lèi)型就絲毫沒(méi)有封裝性可言了看疙。因此我們需要另一種高大上的模式,——原型模式(prototype)