您好,登錄后才能下訂單哦!
工廠模式
1 function createPerson(name,age,job){ 2 var o = new Object(); 3 o.name = name; 4 o.age = age; 5 o.job = job; 6 o.sayName = function(){ 7 console.log(this.name); 8 } 9 return o;10 }11 12 var person1 = createPerson("Nicholas",29,"SoftWare Engineer");13 var person2 = createPerson("Greg",23,"Doctor");
工廠模式雖然解決了創(chuàng)建多個相似對象的問題,但卻沒有解決對象識別的問題(即怎么樣知道一個對象的類型)
構(gòu)造函數(shù)模式
1 function Person(name,age,job){ 2 this.name = name; 3 this.age = age; 4 this.job = job; 5 this.sayName = function(){ 6 console.log(this.name); 7 }; 8 } 9 10 var person1 = new Person("Nicholas",29,"SoftWare Engineer");11 var person2 = new Person("Greg",23,"Doctor");
Person()中的代碼除了與createPerson()中相同的部分外,還存在以下不同之處:
1、沒有顯示的創(chuàng)建的對象
2、直接將屬性和方法賦給了this對象
3、沒有return語句
按照慣例,構(gòu)造函數(shù)始終都應(yīng)該以一個大寫字母開頭,而非構(gòu)造函數(shù)則應(yīng)該以一個小寫字母開頭。
要創(chuàng)建Person的新實(shí)例,必須使用new操作符。以這種方式調(diào)用的構(gòu)造函數(shù)實(shí)際上會經(jīng)歷一下4個步驟
1、創(chuàng)建一個新對象
2、將構(gòu)造函數(shù)的作用域賦給新對象
3、執(zhí)行構(gòu)造函數(shù)中的代碼(為這個新對象添加屬性)
4、返回新對象
person1和person2分別保存著Person的一個不同的實(shí)例。這兩個對象都有一個constructor(構(gòu)造
函數(shù))屬性,該屬性指向Person
1 alert(person1.constructor == Person); //true2 alert(person2.constructor == Person); //true
但是,提到檢測對象的類型,還是instanceof操作符更可靠一些,上面的例子中創(chuàng)建的所有對象即是
Object的實(shí)例,也是Person的實(shí)例。
1 console.log(person1 instanceof Object); //true2 console.log(person1 instanceof Person); //true
創(chuàng)建自定義的構(gòu)造函數(shù)一意味著將來可以將它實(shí)例標(biāo)識為一種特定的類型;而這正是構(gòu)造函數(shù)模式
勝過工廠模式的地方。
1、將構(gòu)造函數(shù)當(dāng)做函數(shù)
構(gòu)造函數(shù)與其他函數(shù)的唯一區(qū)別,就在于調(diào)用他們的方式不同。任何函數(shù),只要通過new操作符來調(diào)用,
那他就可以作為構(gòu)造函數(shù),而任何函數(shù)如果不通過new操作符來調(diào)用,那他和普通函數(shù)沒什么差別
1 //當(dāng)做構(gòu)造函數(shù)使用 2 var person = new Person("Nicholas",29,"Software Engineer"); 3 person.sayName(); //Nicholas 4 5 //作為普通函數(shù)調(diào)用 6 Person("Greg",27,"Doctor"); 7 window.sayName(); //Greg 8 9 //在另一個對象的作用域中調(diào)用10 var o = new Object();11 Person.call(o,"Kristen",25,"Nurse");12 o.sayName(); //Kristen
2、構(gòu)造函數(shù)的問題
構(gòu)造函數(shù)的主要問題就是每個方法都要在每個實(shí)例上重新創(chuàng)建一遍,person1和person2都有一個名為
sayName()的方法,但那兩個方法不是同一個Function實(shí)例
1 console.log(person1.sayName == person2.sayName); //false
為了解決這個問題,通常將函數(shù)定義轉(zhuǎn)移到構(gòu)造函數(shù)外面
1 function Person(name,age,job){ 2 this.name = name; 3 this.age = age; 4 this.job = job; 5 this.sayName = sayName; 6 } 7 8 function sayName(){ 9 console.log(this.name);10 } 11 12 var person1 = new Person("Nicholas",29,"SoftWare Engineer");13 var person2 = new Person("Greg",23,"Doctor");
這樣一來就又出現(xiàn)了新的問題,在全局作用域中定義的函數(shù)sayName()只能被某個對象調(diào)用,這讓全局作用域有點(diǎn)名不副實(shí)。更加嚴(yán)重的是,如果對象需要定義很多方法,那么就要定義很多個全局函數(shù),于是我們這個自定義的引用類型就絲毫沒有封裝性可言了,這些問題都可以通過原型模式來解決
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。