在Javascript面向對象設計一——工廠模式 中介紹了使用CreateEmployee()函數建立員工類。ECMAScript中的構造函數可以用來建立特定類型的對象,如Object和Array這樣的原生構造函數,在運作時會自動出現在執行環境中,此外也可以建立自定義的構造函數,進而建立自定義對象類型的屬性和方法。我們将使用構造函數模式将工廠模式進行改寫。
function Employee(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
alert(this.name);
};
}
var Jim = new Employee("jim", 22, "SoftWare Engineer");
var Sun = new Employee("Sun", 24, "Doctor");
Jim.sayName();
Sun.sayName();
在以上代碼中Employee函數取代了CreateEmployee函數,Employee中的代碼與CreateEmployee中的代碼不同如下:
沒有顯示的建立對象
直接将屬性和方法賦給了this對象
沒有return語句
要建立Employee類的新執行個體,必須使用new操作符,實際會經曆四個步驟:
建立一個新對象
将構造函數的作用域賦給新的對象
執行構造函數中代碼
傳回新對象
以上代碼最後Jim和Sun中分别儲存着Employee的兩個不同執行個體,這兩個執行個體都有一個constructor(構造函數)屬性,該屬性指向Employee,可以做如下測試
alert(Jim instanceof Employee); //true
alert(Sun instanceof Employee);//true
同時這兩個對象又都是Object類型的,可通過如下代碼檢測。
alert(Jim instanceof Object); //true
alert(Sun instanceof Object);//true
建立自定義的構造函數意味着将來可以把它的執行個體标石為一種特定的類型,而這也正是構造函數模式勝過工廠模式的地方。
下面詳細講解一下構造函數:
将構造函數當做函數
構造函數與其他函數的唯一差別就在于調用它們的方式不同。但是構造函數也是函數,不存在定義構造函數的特殊文法。其實,任何函數,隻有通過new來調用,那他就可以作為構造函數,例如,Employee除了以上用new方法調用外,還可以用如下方式來調用。
//作為普通函數調用
Employee("Sun", 28, "SoftWare Engineer"); //添加到window中
window.sayName();//Sun
//在另一個對象的作用域中調用
var o = new Object();
Employee.call(o, "Sun", 28, "SoftWare Engineer");
o.sayName();//Sum
這樣就解決了兩個函數做同一件事情的問題,但是新的問題又會出現了,這個在全局作用域中定義的函數,實際上隻能被某個對象引用,而且最要命的問題是,如果對象需要定義很多方法,那麼就需要定義很多個全局函數,是以這個自定義的引用類型,就沒有任何封裝性可言了.