《javascript設計模式》讀書筆記二(封裝和隱藏信息)
1.為什麽要封裝和信息隱藏
做過編程的朋友們知道“耦合”這個詞。事實上封裝的效果就是為了解耦,讓類和類之間沒有太多的聯系,防止某一天改動某一類的時候,產生“多米骨諾牌效應”。
我們能夠把信息隱藏看成目的,把封裝看成達到信息隱藏的技術。
通過封裝就能夠把對象的內部數據表現形式和實現細節進行隱藏。就好比你會看電視,可是你不知道電視的內部結構一樣。
可是在javascript中沒有不論什麽內置的機制。所以我們還需做些處理,相同來模仿封裝。
2.創建對象的方法
1)最簡單的一種方法就是門戶大開型對象。用一個函數來作為其構造器。所謂的門戶大開就是他的全部的屬性和方法都是公開的。相當於我們經經常使用的keyword“public”。
<span style="font-family:SimSun;font-size:18px;"> <script> //定義一個book的類,function承擔了構造函數的工作 var Book = function (name, title, author) { this.name = name;//書名 this.title = title;//標題 this.author = author;//作者 } //實例化一個book1對象 var book1 = new Book("語文"); alert(book1.name); </script></span>
這是一種最簡單的創建對象的方式。可是它還是無法做到隱藏對象內部的信息。想想看我們在其它編程語言中是怎樣創建對象的呢?
2)vb.net中創建屬性對象
<span style="font-family:SimSun;font-size:18px;">‘定義一個Book類 Public Class Book Dim book As String ‘書名 Dim title As String ‘標題 Dim author As String ‘作者 ‘‘‘ <summary> ‘‘‘ 得到書名 ‘‘‘ </summary> ‘‘‘ <value></value> ‘‘‘ <returns></returns> ‘‘‘ <remarks></remarks> Property GetBook() As String Get Return book End Get Set(value As String) book = value End Set End Property ‘‘‘ <summary> ‘‘‘ 返回title ‘‘‘ </summary> ‘‘‘ <value></value> ‘‘‘ <returns></returns> ‘‘‘ <remarks></remarks> Property GetTitle() As String Get Return title End Get Set(value As String) title = value End Set End Property ‘‘‘ <summary> ‘‘‘ 獲取作者 ‘‘‘ </summary> ‘‘‘ <value></value> ‘‘‘ <returns></returns> ‘‘‘ <remarks></remarks> Property GetAuthor() As String Get Return author End Get Set(value As String) author = value End Set End Property End Class </span>
3.利用閉包模仿VB.NET構造函數
1)看了上述VB.NET的代碼。事實上我們也能夠在javascript去模仿實現,還是上述的操作,定義一個Book類。關於這個類有三個屬性,假設你僅僅想得到的話,能夠僅僅簡單的設置一個get方法。為了區分私有和公有成員,能夠在方法和屬性名稱前加下劃線來區分。
<span style="font-family:SimSun;font-size:18px;"> </span><pre class="javascript" name="code"><span style="font-family:SimSun;font-size:18px;">//定義一個book的類,function承擔了構造函數的工作 var Book = function (name) { this._name = name;//書名 //通過一個內嵌函數,來實現外部的函數可以訪問到內部的私有變量 this._GetName = function () { return this._name; } this._SetName = function (value) { this._name=value } } //實例化一個book1對象 var book1 = new Book("語文"); alert(book1._GetName());//正確 book1._SetName("數學"); alert(book1._GetName());//正確 alert(_name);//錯誤操作 alert(""); </span>
<span style="font-family:SimSun;font-size:18px;">這就是一個簡單的閉包,通過內嵌函數來返回外層函數的私有變量,從而即封裝了內部函數的私有變量又能夠訪問的到。有關於閉包的知識,能夠看我先前的博客。</span>
2)以上的操作還能夠通過原型對象的操作來實現。
<span style="font-family:SimSun;font-size:18px;"><script> //定義一個book的類,function承擔了構造函數的工作 var Book = function (name) { this._name = name;//書名 //通過一個內嵌函數。來實現外部的函數可以訪問到內部的私有變量 } //通過原型對象來設置訪問對象的私有屬性 Book.prototype = { _GetName: function () { return this._name; }, _SetName: function (value) { this._name = value; } } //實例化一個book1對象 var book1 = new Book("語文"); alert(book1._GetName());//正確 book1._SetName("數學"); alert(book1._GetName());//正確 alert(_name);//錯誤操作 alert(""); </script></span>
3)兩種方法對照
能夠看到通過上述兩種操作都能夠封裝不論什麽對象的私有屬性。話又說回來,這兩種操作又有什麽不同呢?
這就涉及到有關原型對象的知識,本節僅僅是單純的實現怎樣封裝隱藏信息,不會在展開討論。
至於把全部的方法都創建到原型對象中,就會無論生成對少對象實例。這些方法在內存中僅僅會存在一份,方法都共用。而還有一個則不同,沒生成一個對象。沒調用一個方法,都會占用一份內存。比方說上述的樣例中創建了5個Book對象。用樣例一中的_GetName方法的話。每一個對象都會占用一份內存,而用原型對象創建的話。五個Book對象共用一份內存,這就是他們最本質的差別。
假設用原型對象創建的方法,在實例化Book1的時候,運行方法時,先從本對象開始尋找,假設找到則停止,未找到則會轉移到原型對象方法中尋找。這也是為何創建的對象能夠共享原型對象方法的本質。
demo
function Person(name, sex) { this.name = name; this.sex = sex; } Person.prototype.age = 20; var zhang = new Person("ZhangSan", "man"); console.log(zhang.age); // 20 // 覆蓋prototype中的age屬性 zhang.age = 19; console.log(zhang.age); // 19 delete zhang.age; // 在刪除實例屬性age後,此屬性值又從prototype中獲取 console.log(zhang.age); // 20
4.小結
以上就是在javascript中模仿構造函數創建對象的方法,事實上與其它語言對照來說,很的簡單。僅僅只是涉及到了一些“閉包”的知識,假設用過其它語言的話,那麽你就會很掌握的。
《javascript設計模式》讀書筆記二(封裝和隱藏信息)