原文出自於本人個人博客網站:https://www.dzyong.com(歡迎訪問)
轉載請註明來源: 鄧佔勇的個人博客 - 《JavaScript設計模式——面對對象的編程》
本文鏈接地址: https://www.dzyong.com/#/ViewArticle/85
面對對象編程是一種程序設計範型。它將對象作爲程序的基本單元,將程序和數據封裝其中,以提高程序的重用性、靈活性和擴展性。
我們以一個例子來開始學習。需求:對用戶輸入的用戶名、郵箱、密碼等進行驗證。
實現這個需求很簡單,小白的寫法是:
function checkName() {
//驗證姓名
}
function checkEmail() {
//驗證郵箱
}
function checkPassword() {
//驗證密碼
}
這是一種函數的形式來進行驗證,但是這種寫法的風險很大,如果是個人開發這樣寫的話問題不大,但是如果是團隊開發,如果別人也定義了同樣的方法就會覆蓋掉原有的功能了。因爲這3個函數屬於全局變量。
用對象收編變量
爲了避免這樣的問題發生,我們可以使用對象收編變量。
var CheckObject = {
checkName : function(){
//驗證姓名
},
checkEmail : function(){
//驗證郵箱
},
checkPassword : function(){
//驗證密碼
},
}
此時將所有的函數作爲CheckObject 對象的方法,這樣我們就只有了一個對象,並且我們使用它也很簡單,比如說檢測姓名 CheckObject.checkName (),只是比原來的前面多了一個對象的名稱。
對象的另一種形式
對象還有另一種形式,可以先聲明對象,然後在爲它添加方法,所以你可以這麼做:
var CheckObject = function(){}
CheckObject .checkName = function() {
//驗證姓名
}
CheckObject .checkEmail = function() {
//驗證郵箱
}
CheckObject .checkPassword = function() {
//驗證密碼
}
真假對象
如果你想複製這個對象可以這樣寫:
var CheckObject = function(){
return {
checkName : function(){ //驗證姓名 },
checkEmail : function(){ //驗證郵箱},
checkPassword : function(){ //驗證密碼},
}
}
這樣做的好處是,每當調用這個函數的時候,把之前的那個對象返回出來,當別人每次調用這個函數的時候都返回一個新的對象,這樣每個人使用時就互不影響了。
var a = CheckObject ();
a.checkName ();
類也可以
雖然創建新對象完成了需求,但是它不是一個真正意義上類 的創建方式,並且創建的對象a和對象CheckObject 沒有任何關係,接下來我們就來創建也真正的類:
var CheckObject = function(){
this.checkName = function(){ //驗證姓名 }
this.checkEmail = function(){ //驗證郵箱 }
this.checkPassword = function(){ //驗證密碼 }
}
類的創建方法就不能像對象那樣,既然是一個類,就要用關鍵字new來創建
var a = new CheckObject ();
a.checkName ();
一個檢測類
所有的方法放在函數內部了,通過this定義的,所以每一次通過new關鍵字創建新對象的時候,新創建的對象就會對類的this上的屬性進行復制。所以這些新創建的對象都有自己的一套方法,但是這麼多有時候造成的消耗是很奢侈的,我們需要處理一下:
var CheckObject = function(){}
CheckObject .prototype.checkName = function(){ //驗證姓名 }
CheckObject .prototype.checkEmail = function(){ //驗證郵箱 }
CheckObject .prototype.checkName = checkPassword (){ //驗證密碼 }
這樣創建對象實例的時候,創建出來的對象所擁有的方法都是一個,因爲他們都要依賴prototype原型一次尋找,而找到的方法都是同一個,他麼都綁定在CheckObject對象類的原型上。當然我們還可以對上面的方式進行簡化。
var CheckObject = function(){}
CheckObject .prototype = {
checkName : function() { //驗證姓名 },
checkEmail : function() { //驗證郵箱 },
checkName : function() { //驗證密碼 },
}
但是千萬要注意,這兩種方式不能混着用,否則一旦混用,如在後面爲對象的原型對象賦值新對象時,它將覆蓋掉之前對prototype對象賦值的方法。
使用還是如同之前一樣的方法使用;
var a = new CheckObject ();
a.checkName ();
a.checkEmail ();
a.checkName ();
方法還可以這樣用
在之前的基礎上還可以進一步的優化,不知你發現沒,調用3個方法我們需要寫3遍a,這是可以避免的,在聲明的每一個方法末尾返回當前對象(JavaScript中this指向當前對象)。
var CheckObject = {
checkName : function() { //驗證姓名 return this; },
checkEmail : function() { //驗證郵箱 return this; },
checkName : function() { //驗證密碼 return this; },
}
此時我們就可以這樣用:
CheckObject .checkName().checkEmail().checkName()
是不是感覺簡潔了很多,當然同樣的方式也可以放到類的原型對象中:
var CheckObject = function(){}
CheckObject .prototype = {
checkName : function() { //驗證姓名 return this; },
checkEmail : function() { //驗證郵箱 return this; },
checkName : function() { //驗證密碼 return this; },
}
var a = new CheckObject();
a.checkName().checkEmail().checkName()
函數的祖先
prototype.js是一款JavaScript框架,裏面爲我們方便的封裝了很多方法,最大的特點就是可以對源生對象(Function、Array、Object等)的擴展,比如你想給一個函數都添加一個郵箱檢測的方法可以這麼做:
Function.prototype.checkEmail = function(){
//驗證郵箱
}
這樣使用這個方法就方便了很多:
函數的形式
var a = function(){}
a.checkEmail ();
類的形式
var a = new Function();
a.checkEmail ();
但是爲了安全我們不允許這麼做,因爲這會污染源生的對象Function,造成不必要的開銷,你可以抽象出一個統一添加方法的功能:
Function.prototype.addMothed = function(name, fn) {
this[name] = fn
}
你就可以使用如下的方式來添加你的方法
var motheds = function() {} 或 var motheds = new Function()
motheds.addMothed('checkEmail ', function(){ // 檢測郵箱 })
同樣也可以鏈式添加
Function.prototype.addMothed = function(name, fn) {
this[name] = fn;
return this;
}
motheds.addMothed('checkEmail ', function(){ // 檢測郵箱 })
.addMothed('checkName', function(){ // 檢測姓名 })
也是返回方法的this來實現
motheds.addMothed('checkEmail ', function(){ // 檢測郵箱 return this; })
使用類調用方式
Function.prototype.addMothed = function(name, fn) {
this.prototype.[name] = fn;
return this;
}
使用類的方式時要注意,不能直接使用,需要通過new關鍵字來創建對象。
var m = new Methods();
m.checkEmail ()
原文出自於本人個人博客網站:https://www.dzyong.com(歡迎訪問)
轉載請註明來源: 鄧佔勇的個人博客 - 《JavaScript設計模式——面對對象的編程》