天天看點

JavaScript面向對象設計二——構造函數模式

在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

構造函數的問題

使用構造函數的主要問題就是都要在每個實力上重新建立一遍,以上兩個對象中的sayname方法其實是不同的function的執行個體,可以用如下方法證明:

alert(jim.sayname == sun.sayname);//false

但是建立兩個完成同樣任務的function執行個體,是以我們對上面的函數進行改寫,如下

function employee(name, age, job) {

this.name = name;

this.age = age;

this.job = job;

this.sayname =sayname;

}

function sayname() {

alert(this.name);

}

這樣就解決了兩個函數做同一件事情的問題,但是新的問題又會出現了,這個在全局作用域中定義的函數,實際上隻能被某個對象引用,而且最要命的問題是,如果對象需要定義很多方法,那麼就需要定義很多個全局函數,是以這個自定義的引用類型,就沒有任何封裝性可言了.

======================================================

在最後,我邀請大家參加新浪APP,就是新浪免費送大家的一個空間,支援PHP+MySql,免費二級域名,免費域名綁定 這個是我邀請的位址,您通過這個連結注冊即為我的好友,并獲贈雲豆500個,價值5元哦!短網址是http://t.cn/SXOiLh我建立的小站每天訪客已經達到2000+了,每天挂廣告賺50+元哦,呵呵,飯錢不愁了,\(^o^)/