JavaScript面向?qū)ο笤O計二 構(gòu)造函數(shù)模式
更新時間:2011年12月20日 01:23:05 作者:
在Javascript面向?qū)ο笤O計一——工廠模式 中介紹了使用CreateEmployee()函數(shù)創(chuàng)建員工類。ECMAScript中的構(gòu)造函數(shù)可以用來創(chuàng)建特定類型的對象,如Object和Array這樣的原生構(gòu)造函數(shù),在運行時會自動出現(xiàn)在執(zhí)行環(huán)境中,此外也可以創(chuàng)建自定義的構(gòu)造函數(shù),從而創(chuàng)建自定義對象類型的屬性和方法
我們將使用構(gòu)造函數(shù)模式將工廠模式進行改寫。
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函數(shù)取代了CreateEmployee函數(shù),Employee中的代碼與CreateEmployee中的代碼不同如下:
沒有顯示的創(chuàng)建對象
直接將屬性和方法賦給了this對象
沒有return語句
要創(chuàng)建Employee類的新實例,必須使用new操作符,實際會經(jīng)歷四個步驟:
創(chuàng)建一個新對象
將構(gòu)造函數(shù)的作用域賦給新的對象
執(zhí)行構(gòu)造函數(shù)中代碼
返回新對象
以上代碼最后Jim和Sun中分別保存著Employee的兩個不同實例,這兩個實例都有一個constructor(構(gòu)造函數(shù))屬性,該屬性指向Employee,可以做如下測試
alert(Jim instanceof Employee); //true
alert(Sun instanceof Employee);//true
同時這兩個對象又都是Object類型的,可通過如下代碼檢測。
alert(Jim instanceof Object); //true
alert(Sun instanceof Object);//true
創(chuàng)建自定義的構(gòu)造函數(shù)意味著將來可以把它的實例標石為一種特定的類型,而這也正是構(gòu)造函數(shù)模式勝過工廠模式的地方。
下面詳細講解一下構(gòu)造函數(shù):
將構(gòu)造函數(shù)當做函數(shù)
構(gòu)造函數(shù)與其他函數(shù)的唯一區(qū)別就在于調(diào)用它們的方式不同。但是構(gòu)造函數(shù)也是函數(shù),不存在定義構(gòu)造函數(shù)的特殊語法。其實,任何函數(shù),只有通過new來調(diào)用,那他就可以作為構(gòu)造函數(shù),例如,Employee除了以上用new方法調(diào)用外,還可以用如下方式來調(diào)用。
//作為普通函數(shù)調(diào)用
Employee("Sun", 28, "SoftWare Engineer"); //添加到window中
window.sayName();//Sun
構(gòu)造函數(shù)的問題
使用構(gòu)造函數(shù)的主要問題就是都要在每個實力上重新創(chuàng)建一遍,以上兩個對象中的sayName方法其實是不同的Function的實例,可以用如下方法證明:
alert(Jim.sayName == Sun.sayName);//false
但是創(chuàng)建兩個完成同樣任務的Function實例,所以我們對上面的函數(shù)進行改寫,如下
function Employee(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName =sayName;
}
function sayName() {
alert(this.name);
}
這樣就解決了兩個函數(shù)做同一件事情的問題,但是新的問題又會出現(xiàn)了,這個在全局作用域中定義的函數(shù),實際上只能被某個對象引用,而且最要命的問題是,如果對象需要定義很多方法,那么就需要定義很多個全局函數(shù),所以這個自定義的引用類型,就沒有任何封裝性可言了.
復制代碼 代碼如下:
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函數(shù)取代了CreateEmployee函數(shù),Employee中的代碼與CreateEmployee中的代碼不同如下:
沒有顯示的創(chuàng)建對象
直接將屬性和方法賦給了this對象
沒有return語句
要創(chuàng)建Employee類的新實例,必須使用new操作符,實際會經(jīng)歷四個步驟:
創(chuàng)建一個新對象
將構(gòu)造函數(shù)的作用域賦給新的對象
執(zhí)行構(gòu)造函數(shù)中代碼
返回新對象
以上代碼最后Jim和Sun中分別保存著Employee的兩個不同實例,這兩個實例都有一個constructor(構(gòu)造函數(shù))屬性,該屬性指向Employee,可以做如下測試
復制代碼 代碼如下:
alert(Jim instanceof Employee); //true
alert(Sun instanceof Employee);//true
同時這兩個對象又都是Object類型的,可通過如下代碼檢測。
復制代碼 代碼如下:
alert(Jim instanceof Object); //true
alert(Sun instanceof Object);//true
創(chuàng)建自定義的構(gòu)造函數(shù)意味著將來可以把它的實例標石為一種特定的類型,而這也正是構(gòu)造函數(shù)模式勝過工廠模式的地方。
下面詳細講解一下構(gòu)造函數(shù):
將構(gòu)造函數(shù)當做函數(shù)
構(gòu)造函數(shù)與其他函數(shù)的唯一區(qū)別就在于調(diào)用它們的方式不同。但是構(gòu)造函數(shù)也是函數(shù),不存在定義構(gòu)造函數(shù)的特殊語法。其實,任何函數(shù),只有通過new來調(diào)用,那他就可以作為構(gòu)造函數(shù),例如,Employee除了以上用new方法調(diào)用外,還可以用如下方式來調(diào)用。
復制代碼 代碼如下:
//作為普通函數(shù)調(diào)用
Employee("Sun", 28, "SoftWare Engineer"); //添加到window中
window.sayName();//Sun
復制代碼 代碼如下:
//在另一個對象的作用域中調(diào)用
var o = new Object();
Employee.call(o, "Sun", 28, "SoftWare Engineer");
o.sayName();//Sum
var o = new Object();
Employee.call(o, "Sun", 28, "SoftWare Engineer");
o.sayName();//Sum
構(gòu)造函數(shù)的問題
使用構(gòu)造函數(shù)的主要問題就是都要在每個實力上重新創(chuàng)建一遍,以上兩個對象中的sayName方法其實是不同的Function的實例,可以用如下方法證明:
alert(Jim.sayName == Sun.sayName);//false
但是創(chuàng)建兩個完成同樣任務的Function實例,所以我們對上面的函數(shù)進行改寫,如下
復制代碼 代碼如下:
function Employee(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName =sayName;
}
function sayName() {
alert(this.name);
}
這樣就解決了兩個函數(shù)做同一件事情的問題,但是新的問題又會出現(xiàn)了,這個在全局作用域中定義的函數(shù),實際上只能被某個對象引用,而且最要命的問題是,如果對象需要定義很多方法,那么就需要定義很多個全局函數(shù),所以這個自定義的引用類型,就沒有任何封裝性可言了.
您可能感興趣的文章:
- Javascript面向?qū)ο缶幊蹋ㄈ?非構(gòu)造函數(shù)的繼承
- Javascript面向?qū)ο缶幊蹋ǘ?構(gòu)造函數(shù)的繼承
- JS面向?qū)ο蠡A講解(工廠模式、構(gòu)造函數(shù)模式、原型模式、混合模式、動態(tài)原型模式)
- js面向?qū)ο笾R妱?chuàng)建對象的幾種方式(工廠模式、構(gòu)造函數(shù)模式、原型模式)
- js面向?qū)ο笤O計用{}好還是function(){}好(構(gòu)造函數(shù))
- js實現(xiàn)輪播圖的兩種方式(構(gòu)造函數(shù)、面向?qū)ο?
- 不用構(gòu)造函數(shù)(Constructor)new關(guān)鍵字也能實現(xiàn)JavaScript的面向?qū)ο?/a>
- 深入理解javascript構(gòu)造函數(shù)和原型對象
- JavaScript 構(gòu)造函數(shù) 面相對象學習必備知識
- js構(gòu)造函數(shù)創(chuàng)建對象是否加new問題
- 淺談javascript構(gòu)造函數(shù)與實例化對象
- JS面向?qū)ο缶幊袒A篇(一) 對象和構(gòu)造函數(shù)實例詳解
相關(guān)文章
javascript 混合的構(gòu)造函數(shù)和原型方式,動態(tài)原型方式
JS編程中最常用兩種對象類定義的方式。不管是利用下面2種方式的那一種,都可以達到相同的效果!2009-12-12javascript 面向?qū)ο笕吕砭氈當?shù)據(jù)的封裝
JavaScript 是一種非常靈活的面向?qū)ο蟪绦蛟O計語言,它與傳統(tǒng)的強類型的面向?qū)ο蟪绦蛟O計語言(如 C++,Java,C# 等)有很大不同,所以要實現(xiàn)如 C++、java、C# 當中的一些特性就需要換一種思考方式來解決。2009-12-12JavaScript面向?qū)ο?極簡主義法minimalist approach)
荷蘭程序員 Gabor de Mooij 提出了一種比 Object.create ()更好的新方法,他稱這種方法為極簡主義法(minimalist approach)。這也是我推薦的方法2012-07-07XRegExp 0.2: Now With Named Capture
XRegExp 0.2: Now With Named Capture...2007-11-11JavaScript面向?qū)ο笤O計二 構(gòu)造函數(shù)模式
在Javascript面向?qū)ο笤O計一——工廠模式 中介紹了使用CreateEmployee()函數(shù)創(chuàng)建員工類。ECMAScript中的構(gòu)造函數(shù)可以用來創(chuàng)建特定類型的對象,如Object和Array這樣的原生構(gòu)造函數(shù),在運行時會自動出現(xiàn)在執(zhí)行環(huán)境中,此外也可以創(chuàng)建自定義的構(gòu)造函數(shù),從而創(chuàng)建自定義對象類型的屬性和方法2011-12-12Javascript 面向?qū)ο缶幊?coolshell)
Javascript是一個類C的語言,他的面向?qū)ο蟮臇|西相對于C++/Java比較奇怪,但是其的確相當?shù)膹姶?,?Todd 同學的“對象的消息模型”一文中我們已經(jīng)可以看到一些端倪了2012-03-03一實用的實現(xiàn)table排序的Javascript類庫
一實用的實現(xiàn)table排序的Javascript類庫...2007-09-09