首頁 > web前端 > js教程 > 主體

JavaScript設計模式之一封裝

高洛峰
發布: 2016-11-25 11:03:01
原創
1048 人瀏覽過

對於熟悉C#和Java的兄弟們,面向對象的三大思想(封裝,繼承,多態)肯定是了解的,今天我想講講如何在Javascript中利用封裝這個特性,開講!

我們會把現實中的一些事物抽象化成一個Class並且把事物的屬性(名詞)當作Class的Property把事物的動作(動詞)當作Class的methods。在物件導向的語言中(C#等)都會有一些關鍵字來修飾類別或屬性(Private,public,protect),這些關鍵字描述了存取的權限,不多做解釋。

我們來看看Javascript的易變的特性(我們也用上一次的例子):


var Man = function (name, age) {                }      var Person = new Interface("Person", ["GetName", "GetAge"]);            Man.prototype = { GetName: function () { return this.Name; },     } var Alan = new Man("Alan", 25);      alert(Alan.GetAge());    Alan.DisplayAll = function () { return "Name: "+this.GetName() + "; Age: " + this. GetAge() }   alert(Alan.DisplayAll());


我先創建了一個Class(Javascript的匿名方法)擁有2個公共的(public)的字段(這篇blog會詳細講解,繼續往下看)和2個public的方法,我們創建了一個Instance--Alan,但是我可以為這個Instance動態的添加一個DisplayAll的方法,我想任何面向對象的語言是做不到這一點的,Javascript的靈活體現之一。

我們現在假設一個場景,如果有很多的程式設計師要用這段程式碼,由於Javascript的易變性,程式設計師就可以在實例化後改變Name的值,那初始化的動作就沒有意義了:


 var Alan = new Man("Alan", 25);       Alan.Name = "Alice"; //悲劇了,我alert的時候變成Alice了       alert(Alan.GetName());讓外部的人去任意的修改這個字段,在Java或C#中我們只需要個這個字段改為Private,就萬事OK了,但是Javascript沒有這個關鍵字,那我們需要這麼做呢,這就是這篇blog存在的意義

我們可以想下在C#除了設定Private之外我們還可以怎麼做?我們可以設定Setter和Getter方法。

我們來修改下上面的程式碼:我們稱方法一:

 var Person = new Interface("Person", ["SetName", "SetAge", "GetName", "GetAge  var function (name, age) {            this.SetAge(age);            this.SetName()      SetName: function (name) { this.Name = name; },            SetAge: function (age) { this Alan.Age = age; },            GetName: function () { return this.Name; },           new Man("Alan", 25);       Alan.Name = "Alice"; //悲劇了,我alert的時候變成Alice了       Alan.SetAge(10);//悲劇,被別人把我的年齡給這麼小       alert(Alan.GetName()); function () { return "Name: "+this.GetName() + "; Age: " + this.GetAge() }       alert(Alan.DisplayAll());


我們發現似貌如C#中的似貌和Getter,但是還是可以被外部修改。但是從約束上來看,似乎比上面的code好看些,透過方法來設定初始值。但是問題還是沒有解決,我們來看看下面一種方法:閉包

//我需要解釋一下,在Javascript中是透過This關鍵字來開發權限的(Public)。

在講閉包之前,我們需要了解下閉包的本質: 在Javascript中,只有方法是有作用域的,如果在方法中聲明的變數在外部是無法訪問的,那Private的概念就出來了。


var Person = new Interface("Person", ["SetName", "SetAge", "GetName", "GetAge"]);       var Man = f             this.SetName = function (newname) { name = newname; }               this.SetAge = function (newage) {age = newage; }              this.GetAge = function () { return age; }               this Alan.SetAge(newage);               this.SetName(newname);           現在name是private了,我是無法去修改的       Alan .SetAge(10); //悲劇,被別人把我的年齡給這麼小      alert(Alan.GetAge());


現在私有的功能就實現了,我們只是用Var來代替了This而已。 //我們把公共(Public)並且可以訪問Private的方法稱為特權方法,例如上面的this.SetName, this.SetAge.

如果我們的公共方法不涉及到訪問Private的字段,那我們可以把他們放到Prototype中。 //好處是多個實例的時候記憶體中也只有一分拷貝


Man.prototype.DisplayAll = function () { return "Name: " + this.GetName() + "; Age: " + this.GetAge () }


哈哈~我們來看下稍微有點難度的東西:靜態變數和方法

我們都是知道靜態的東西屬於類別(Class),我們來修改下上面的程式碼:


var Person = new Interface("Person", ["SetName", "SetAge", "GetName", "GetAge","GetCount"]);      var Man = (function () {     ) {              var name, age;              this.SetName = c age) { age = newage; }              this.GetName = function () { return name; }         = function () { return age; }              this.GetCount = function () { return count; }        .SetName(newname);              count++;          }     () { return "Name: " + this.GetName() + "; Age: " + this.GetAge() }          var Alan1 = new Man("Alan", 25);   25);     alert("There are "+Alan2.GetCount()+" instances of Man" );


相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板