Javascript設計模式學習1(熱身篇)

從建立一個函數開始

函數的建立有不少形式,一般咱們會採用如下作法javascript

function getName(){
    //get name here
}
function getAge(){
 //get age here
}

var getName = function(){
    //get name here
}
var getAge= function(){
 //get age here
}
複製代碼

可是這種作法有個弊端,這類函數由於都是全局變量,因此在團隊合做,或者項目函數不少時就會出現函數命名重複的問題,那就糟糕了,會出現函數被覆蓋,致使沒必要要的工做量。因此能夠採用下面的方式(用對象來收編方法,變量)java

var GetUserInfo= {
    getName:function(){
        //get name here
    },
    getAge :function(){
        //get age here
    }
}
//或者像下面這樣
var GetUserInfo= function(){};
GetUserInfo.getName = function(){
 //get name here
},
GetUserInfo.getAge = function(){
 //get age here
 }

複製代碼

可是上面方法,還有個問題,就是這個對象不能複製,好比我只想使用裏面的getUserInfo.getAge()這個方法,可是沒有辦法複製一個這樣的對象來給本身使用,除非代碼所有拷貝一遍,這無疑徒增了代碼量,因此咱們能夠採用return來返回一個新的函數對象,以下編程

var GetUserInfo= function(){
 return {
     getName :function(){
         //get name here
     },
     getAge : function(){
         //get age here
     }
 }
}
複製代碼

這樣咱們就能夠安心複製getUserInfo其中的某個方法來爲本身所用了,使用方法以下函數

var getUserInfo_myself = GetUserInfo()
getUserInfo_myself.getName()
複製代碼

上面的方法雖然能夠完美達到咱們的要求,可是編程最重要的是什麼?固然時面向對象!咱們來回顧一下面向對象的三個基本特徵:封裝、繼承、多態。優化

封裝:類其實就是保存了一個函數的變量,這個函數有本身的屬性和方法。將屬性和方法組成一個類的過程就是封裝。ui

因此要實現封裝,咱們就得用JS實現一個類this

//ES5
var GetUserInfo= function(){
    this.getName = function(){
         //get name here
     },
     this.getAge = function(){
         //get age here
     },
}
//this的指向簡單理解就是函數被調用時的執行環境,也能夠說時誰調用該函數,this就指向誰
//這裏this就指向getUserInfo_myself

複製代碼

上面的代碼(構造函數)就實現了一個類(函數,有本身的屬性,有本身的方法)spa

調用時,咱們就不能var getUserInfo_myself = GetUserInfo()這樣來用了。要像下面這樣prototype

var getUserInfo_myself = new GetUserInfo()
getUserInfo_myself()
複製代碼

覺得這樣就結束?這還不算是最好的方案,由於經過new來建立新對象的時候,新建立的對象都會複製一次this的屬性,用多了就會形成不少消耗,咱們能夠避免嗎?能夠!經過原型的方式來實現,看下面code

//ES5方法一
var GetUserInfo=function(){};
GetUserInfo.prototype.getName={
    //get name here
}
GetUserInfo.prototype.getAge={
  //get age here
}
//ES5方法二
var GetUserInfo=function(){};
GetUserInfo.prototype={
    getName(){
     //get name here
    }
    getAge(){
     //get agehere
     }
}

//用ES6的語法
class GetUserInfo{
 constructor(){}
 getName(){
 //get name here
 }
 getAge(){
 //get age here
 }
}

複製代碼

使用方法以下

var getUserInfo_myself = new GetUserInfo()
// class方法必須使用new,不然會報錯
getUserInfo_myself.getName()
getUserInfo_myself.getAge()
複製代碼

以前的例子中咱們想要執行getName和getAge方法都要將對象getUserInfo_myself寫兩次,那咱們就能夠用鏈式調用來優化一下,那咱們應該怎麼作?看下面

//建立對象的方式實現
var GetUserInfo= {
 getName: function(){
 console.log('getName')
 console.log(this)
 return this
 },
 getAge: function(){
 console.log('getAge')
 console.log(this)
 return this
 }
}
GetUserInfo.getName().getAge()
//這裏的this指向GetUserInfo,因此GetUserInfo.getName().getAge()其實就是這樣執行的
//1. GetUserInfo.getName() 返回this,this指向GetUserInfo,GetUserInfo有兩個方法getName()和getAge()
//2. this.getAge() 也就是 GetUserInfo.getAge()

//原型的方式實現
var GetUserInfo = function(){}
GetUserInfo.prototype={
    getName(){
         //get name here
         return this
     }
     getAge(){
         //get agehere
         return this
     }
}
複製代碼
相關文章
相關標籤/搜索