1. 程式人生 > >《javascript設計模式》讀書筆記二(封裝和隱藏信息)

《javascript設計模式》讀書筆記二(封裝和隱藏信息)

mil del ims 是你 信息 私有屬性 bsp delet urn

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設計模式》讀書筆記二(封裝和隱藏信息)