對上一章節的原廠模式進行代碼重寫
function Human(name, sex) { this.name = name; this.sex = sex; this.say = function () { alert(this.name); } } var man = new Human("漢武大帝", "男"); var woman = new Human("王母娘娘","女");
到Human沒有.他的第一個字母大寫了.這是一種文法約定.建構函式始終應該以一個大寫字母開頭,而非建構函式則以一個小寫字母開頭,用於區分建構函式和非建構函式.
要建立Human的執行個體,必須使用new操作符.這就會出現以下四個步驟:
1.建立一個新對象或變數.
2.將建構函式的範圍賦值給新變數或新對象.
3.執行建構函式中的代碼
4.返回新對象.
1 alert(man instanceof Object);//true
2 alert(man instanceof Human); //true
3 alert(woman instanceof Object); //true
4 alert(woman instanceof Human); //true
這裡的true很好的說明了:建立自訂的建構函式意味著將來可以將他的執行個體表示為一種特定的類型.而這正是構造韓式模式優於原廠模式的地方.
儘管如此,建構函式還是有自己的一些缺陷,或者說不足吧.
在man和woman中都有一個名為say()的方法,他們的功能一模一樣.但是這兩個方法卻不是同一個Function()執行個體建立出來的.
1 function Human(name, sex) {
2 this.name = name;
3 this.sex = sex;
4 this.say = new Function("alert(this.name);");
5 }
這就意味著如果需要n個執行個體,就要建立n個say的Function()執行個體.這樣還是會造成資源的浪費.
繼續對上面的代碼經行最佳化,讓這個say()方法只建立一次.共用一個引用.
function Human(name, sex) { this.name = name; this.sex = sex; this.say = say; } function say() { alert(this.name); }
因為say包含一個指向函數的指標,因此Human的執行個體就共用了全域範圍中的同一個say()函數.但這個無法讓人接受,
因為如果系統比較龐大的話,就會出現很多全域變數,一不小心就會有被改掉的危險.而我們封裝的對象就沒有封裝性可言了.
接著就又有了原型模式了.下一章在接著說原型模式.