最近在實習公司寫代碼,被隔壁的哥們吐槽說,代碼寫的沒有一點藝術。為了讓我的代碼多點藝術,我就重新溫故了《javascript高級程序設計》(其中幾章),然後又看了《javascript設計模式》,然後覺得要寫點心得體會,來整理自己所學的吧。以下是我個人見解,錯了請輕噴,歡迎指出錯誤,樂於改正。
一、封裝
(1)封裝通俗的說,就是我有一些秘密不想讓人知道,就通過私有化變量和私有化方法,這樣外界就訪問不到了。然後如果你有一些很想讓大家知道的東西,你就可以通過this創建的屬性看作是對象共有屬性和對象共有方法,這樣別人知道你的公共的東西啦,不止如此,你還可以訪問到類或對象自身的私有屬性和私有方法。哇,這種權利好大呀,外面的公共的方法和屬性,和內部的私有屬性和方法都可以訪問到,都有特權啦,因此就叫做特權方法了。看個例子就知道啦。
類的內部this上定義的屬性和方法自然就可以復制到新創建的對象上,成為對象公有化的屬性和方法,又可以訪問私有屬性和私有方法,因此就叫特權方法。
這樣調用就可以啦
(2)閉包實現的封裝
閉包是有權訪問另外一個函數作用域中變量的函數,即在一個函數內部創建另外一個函數。這時就可以將閉包作為創建對象的構造函數,這樣它既是閉包又是可實例對象的函數。
二、繼承
(1)類
每個類有3個部分:1,是構造函數內的,是供實例化對象復制用的。2,是構造函數外的,直接通過點語法添加的,這是供類使用的,實例化對象是訪問不到的。3,是類的原型中的,實例化對象可以通過其原型鏈簡介地訪問到,也是為供所有實例化對象所共有的。
(2)類式繼承
通過子類的原型prototype對象實例化來實現的
繼承就是聲明2個類,不過類式繼承需要將第一個類的實例賦值給第二個類的原型。這段代碼,在實現subClass繼承superClass時是通過將superClass的實例賦值給subClass的原型prototype,所以subClass.prototype繼承了superClass.
缺點就是:一個子類的實例原型從父類構造函數中繼承來的共有屬性就會直接影響到其他子類。比如:
額外知識點:instanceof是通過對象的prototype鏈來確定這個對象是否是某個類的實例,而不關心對象與類的自身結構。
(3)構造函數式繼承
構造函數式繼承是通過在子類的構造函數作用環境中執行一次父類的構造函數來實現的。
SuperClass.call(this,id);是構造函數式繼承的精華,call可以更改函數的作用環境。這個對SuperClass調用這個方法就是將子類中的變量子啊父類中執行一遍,由於父類中是給this綁定屬性的,因此子類自然也就繼承了父類的共有屬性。由於這種類型的繼承沒有涉及原型prototype,所以父類的原型方法自然不會被子類繼承,而如果要想被子類繼承就必須要放在構造函數中。
(4)組合繼承
組合繼承就是:類式繼承+構造函數繼承
這裡用例子來測試下
果然子類的實例中更改父類繼承下來的引用類型屬性如books,根本不會影響到其他實例,並且子類實例化過程中又能將參數傳遞到父類的構造函數中。
(5)原型式繼承
原型式繼承跟類式繼承一樣,父類對象book中的值類型的屬性被復制,引用類型的屬性被共有。
(6)寄生式繼承
通過在一個函數內的過渡對象實現繼承並返回新對象的方式,稱之為寄生式繼承。
寄生就像寄生蟲一樣寄托於某個對象內部生長。就是對原型繼承的第二次封裝,並且在這第二次封裝過程中對繼承的對象進行了擴展,這樣新創建的對象不僅僅有父類中的屬性和方法而且還添加了新的屬性和方法。
看下下面的例子吧
(7)寄生組合式繼承
寄生組合式繼承就是寄生式繼承+構造函數式繼承,
先創建了父類,還有父類的原型方法,然後創建子類,並在構造函數中實現構造函數式繼承,然後又通過寄生式繼承了父類 原型,最後又對子類添加了一些原型方法。
現在我們來測試一下
顯然不會出現子類調用之後,另一個子類的值被改變。在這裡其中最大的改變是對子類原型的處理,被賦予父類原型的一個引用,這是一個對象。
(8)多繼承
通過這種方式對一個對象屬性的復制繼承,將多個父類(對象)的屬性與方法拷貝給子類實現繼承
三、多態
多態就是通過對傳遞的參數判斷來執行邏輯,即可實現一種多態處理機制
下面就是這個例子,通過多態類,調用add運算方式,根據不同參數做運算
這就是面向對象的三種特性啦,封裝、繼承、多態,對原理的理解,能在看其他人的優秀代碼的時候,有個很好的理解。