標籤:function san 本質 code returns 通過 執行個體 建立 讀書筆記
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 PropertyEnd 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設計模式》讀書筆記二(封裝和隱藏資訊)