標籤:turn code 靜態屬性 編程思想 blog 添加 方法 return style
一、封裝
物件導向編程思想其中的一個特點就是封裝,通俗的講法就是把需要的功能方向在一個對象裡。遺憾的是,對於JS這種解釋性的弱類型語言沒有經典強型別語言中那樣通過class等關鍵字實作類別的封裝方法,js中都是通過一些特性模仿實現的,雖然這是個弊端,但也帶來了極高的靈活性。
我們看一個Book類是如何通過JS實現的:
1 // 寫法1 2 var Book = function (id, name, pirce) { 3 this.id = id 4 this.name = name 5 this.price = pirce 6 } 7 8 /* 9 * 以下兩種方式不可混用10 */11 12 // 也可以通過在類的原型對象prototype上添加屬性和方法,有兩種方式13 // 一種是一一為原型對象屬性賦值14 Book.prototype.display = function () {15 // ...16 }17 18 // 一種是將一個對象賦值給類的原型對象19 Book.prototype = {20 display: function () {21 // ...22 }23 }
這樣,我們就將所需要的方法和屬性都封裝在我們抽象的Book類裡面,當使用功能方法時,我們不能直接使用Book類,需要用new關鍵字來執行個體化新的對象,並通過點文法來訪問對象的屬性或者方法。比如:
1 var book = new Book(10, ‘書‘, ‘50‘)2 console.log(book.name) // 書
從代碼可以看出,我們通過this添加了屬性,通過prototype添加了方法,那麼這兩者有什麼區別?
通過this添加的屬性和方法是在當前對象上添加的,然而JS是一種基於原型的prototype的語言,所以每次建立一個新對象時,通過prototype繼承的方法並不是對象自身的,所以在使用這些方法時,需要通過prototype一級一級尋找的來,而通過this定義的屬性或者方法是該對象自身所擁有的,所以我們每次建立一個新對象時,this指向的屬性和方法都會得到相應的建立。
二、屬性與方法封裝
在OOP中,既然是類,必定有私人屬性,私人方法,共有屬性,共有方法等這些概念,那麼JS中又是如何去實現呢?
由於JS的函數作用於,聲明在函數內部的變數以及方法在外界是訪問不到的,通過次特性可以建立類的私人變數以及私人方法,然而在函數內部通過this建立的屬性和方法,在類建立對象時,每個對象自身都擁有一份並且可以在外部存取到,因此這些屬性和方法可以看作為共有的,還是Book為例:
1 // 私人屬性與私人方法,特權方法,對象共有屬性和對象公有方法 2 var Book = function (id, name, price) { 3 // 私人屬性 4 var num = 1 5 // 私人方法 6 function checkId () { 7 // ... 8 } 9 // 特權方法10 // 所謂的特權方法,是既可以被外部存取到,又可以訪問類內部的私人屬性與方法的方法11 this.getName = function () {12 // ...13 }14 this.getPrice = function () {15 // ...16 }17 this.setName = function () {18 // ...19 }20 this.setPrice = function () {21 // ...22 }23 // 對象公有屬性24 this.id = id 25 // 對象公有方法26 this.copy = function () {27 // ...28 }29 30 }
而在OOP中,還有兩個概念是:靜態屬性與靜態方法,這兩種東西都屬於類所有,而不屬於每一個對象,調用也只能通過類名加上點文法來使用,那麼JS中如何?呢?
其實很簡單,我們可以在類定義的外面,通過點文法定義屬性以及方法,這樣,通過new關鍵字建立時,這寫在類外面通過點文法添加的屬性和方法是不會被執行到的,因而只能被類本身所調用,我們也就達到了模仿靜態屬性與方法的目的。
1 // 類靜態公有屬性(對象不能訪問)2 Book.isChinese = true3 // 類靜態公有方法(對象不能訪問)4 Book.getIsChinese = function () {5 return Book.isChinese6 }
JavaScript設計模式:一、物件導向編程(第二節)