天天看點

Javascript設計模式學習(二)封裝續

有一個避免其他程式員無意間寫出重名函數的辦法,在你想作為私有屬性或者私有方法的命名前加一個下劃線,像這樣 this._name = name;,這樣雖然不能避免所有的錯誤,但是能夠避免絕大多數的無意識命名引起的沖突。

Scope,Nested Functions,and Closures

在實作私有屬性的封裝之前,我們需要一些基礎的概念支援。在Javascript中,隻有函數擁有作用域,也就是說,函數内部定義的變量,在外部是無法通路的。隻有函數外部定義的變量,在函數内部才能通路。下面是一個說明的例子:

function foo(){

    var = 10;

    function bar(){

    a *= 2;

}

bar();

return a;

在這個例子中,a被定義在foo函數中,可是函數bar中可以通路a,是因為bar函數被定義在了foo函數中。當bar被執行時,他就能夠使a的值翻倍,這是bar在foo内部執行,如果bar在foo外部執行會怎麼樣呢,看下面的例子:

    var a = 10;

        a *= 2;

        return a;

return bar;

var baz = foo();

baz();    //傳回20;

baz();    //傳回40;

baz();    //傳回80;

上例中函數傳回的是一個對于bar的引用,把這個引用傳遞給baz,在執行的時候,他仍可以通路變量a。這是為什麼呢?因為Javascript支援語義上作用域,函數運作是在他被定義的域中,而不是他在被執行的域中。這個例子中bar因為被定義在foo的内部,是以當他在外部被執行時,仍然可以通路内部的變量a。

    以上就是一個Closure的例子,隻有foo中被傳回的函數能夠通路foo中的變量,最常見的建立Closure的方法就是傳回一個Nested Function。

利用Closure建立私有方法

有了上面的基礎,我們就能夠實作私有方法了,如下:

            var

NewHouse

=

function(hid,hname,address){

                var

_hid,_hname,_address;

                function

isValid(hid){

                    if(hid

!=

null

&&

hid

undefined

&

""){

                        return

true;

                    }else{

false;

                    }

                }

                this.getHid

function(){

                    return

_hid;

                this.setHid

function(hid){

                    if(!isValid(hid)){

                        _hid

hid;

                this.getHname

_hname;

                this.setHname

function(hname){

                    _hname

hname

||

"暫無";

                this.getAddress

_address;

                this.setAddress

function(address){

                    _address

address

                this.setHid(hid);

                this.setHname(hname);

                this.setAddress(address);

            }

            NewHouse.prototype.ShowHouse

                document.getElementById("container").innerHTML

+=

"樓盤名稱:"

+

this.hname

"<br />";                

可以看到,之前的例子中一直用this關鍵字來引用屬性,而我們這裡用了var來定義屬性,是以屬性在對象外是不能夠被通路的。對于一些公共的方法,我們仍然可以利用prototype來定義他們。

    這個方法的缺陷是我們每建一個對象,對于内部的方法對要被初始化一下,而這是要消耗記憶體的,我們執行個體的對象越多,消耗的記憶體也就越多。是以這個方法隻試用在真正需要私有化屬性和方法的地方,其他的地方我們仍然可以用完全暴露的方法來做。

繼續閱讀