面向對象的JavaScript(如何一步步成爲js高手)

‘工欲善其事,必先利其器’,在深刻學習JavaScript以前,我認爲咱們頗有必要了解如下,JavaScript這門面向對象的動態語言究竟是一門什麼樣的語言。git

JavaScript vs 其餘面嚮對象語言

  • 它沒有使用像Java等傳統的面嚮對象語言的類式繼承,而是經過原型委託的方式來實現對象間的繼承;
  • 它沒有在語言層面提供對抽象類和接口的支持。
  • 動態類型語言(它可讓開發者將更多的精力放在業務邏輯上,代碼量更少;但它因爲沒法肯定變量的類型,從而使程序可能發生一些與類型相關的錯誤)

    動態類型語言對變量類型的寬容,給實際編碼帶來了很大的靈活性。因爲無需進行類型的 檢測,咱們能夠嘗試調用任何對象的任何方法,而無需考慮它本來是否被設計爲擁有該方法。github

    說到這裏,咱們就不得不提一下鴨子類型了。鴨子類型就說偶們只關注對象的行爲,而不關注對象自己。編程

    咱們知道JavaScript是面向接口編程的語言,而非是面向實現編程的。所以只要咱們給對象添加pop,push方法,增添length屬性,那麼這個對象就能夠當數組使用。設計模式

    雖然,JavaScript也是面向疾苦的語言,可是,它和靜態類型語言的面向接口編程不一而足。數組

面嚮對象語言的特性

多態

它將可變的部分與不可變的部分分離開來,吧可變的部分封裝起來(對象擁有相同的類型,都有相同的方法,接受相同的調用,卻返回不一樣的結果)瀏覽器

下面是一個對象的多態:函數

var robotA = {
    dance: function() {
        console.log('robtA')
    }
};

var robotB = {
    dance: function() {
        console.log('robtB')
    }
}

var robotAction = function(robot) {
    if(robot.dance instanceof Function)
    robot.dance()
}

robotAction(robotA); // robtA
robotAction(robotB); // robtB

在JavaScript中函數被看成第一等對象,也便是說函數自己也是對象,咱們知道由於js是動態類型語言,因此函數不只能夠用來封裝行爲,而且能夠被看成參數四處傳遞。當咱們對函數發起調用時,函數會返回不一樣的結果,這是多態的一種體現,也是不少設計模式能被高階函數代替實現的緣由。學習

封裝

封裝的目的是將信息隱藏。編碼

封裝包括數據的封裝,實現的封裝和 變化的封裝。prototype

1.數據的封裝

在js中咱們只能依賴變量的做用域來進行封裝。能夠實現全局做用域和局部做用域,在ES6以前咱們使用函數來建立做用域,但在以後咱們也可用let來建立做用域。

2.實現的封裝

實現的封裝使得對象的內部變化對其餘對象來講是不可見的。對象對他本身的行爲負責,其餘對象不關心它的內部實現。

封裝使得對象間的耦合變得鬆散,對象間只能經過暴露的API接口進行通訊,只要咱們不修改對象的對外接口,怎麼樣修改對象都不會影響其餘對象的功能。

3.變化的封裝

它就是將應用中穩定的部分和變化的部分隔離開來。若是咱們將變化的部分封裝起來,那麼在應用的開發中咱們將很容易的實現替換。這樣能夠最大程度的保證應用的穩定性和可擴展性。

原型繼承和原型設計模式

前面咱們已經說過JavaScript沒有類式繼承,取而代之的是原型的繼承,這是語言的開發者根本就沒打算在js中引入類這個概念,而是引入了原型的概念。

在原型的編程思想中對象是經過複製而來的,克隆而來的對象與原對象看不出什麼區別。

說到克隆對象,在ES5中有一個Object.create()方法來實現克隆,這個方法有兼容性問題,若是要在只支持ES3的瀏覽器中這就有一個問題。咱們通常用下面的代碼來解決:

Object.create = Object.create || function(obj) {
    var F = function() {};
    F.prototype = obj;
    return new F()
}

在js這種類型模糊的語言中,建立對象很容易,也不存在類型耦合的狀況。

js中的對象的實現是經過js的原型系統來實現的,前面也說過在js中一切皆對象,因此,要想很好的掌握js就要認真研究一下它的原型。

根據JavaScript的設計者本意,除了undefined以外的全部數據都是對像,咱們知道js中的對象都是經過原型克隆而來的的,而在js中對象爲Object,因此數據都是經過Object.prototype而來的(Object對象克隆自Function)。示例代碼以下:

var animal = { name: 'lzb' }; 
var person = function(){};
person.prototype = animal;
var lzb = new person();
console.log( lzb.name ); // lzb

其實嚴格意義上來講實現對象的構造器有原型,若是對象的請求無響應,對象把它的請求委託給它的構造器的原型。

原型繼承有將來嗎

這個在網上說法不一,有的人認爲原型繼承很爛,而且說既然人們總結出了JavaScript的設計模式,而模式的出現自己就意味着語言的不足。可是,有的人認爲它在將來至關長的一段時間仍是有市場的,而且js自己就在自我矯正,用一些新的特性來代替設計模式,ES5中的Object.create()來代替原型模式克隆對象,而ES6中的class的引入也是這個緣由,雖然其背後的實現仍是原型來克隆對象,但它的出現的確解決了必定的問題。再加上如今開發人員對它的興趣大增,因此我認爲原型繼承有將來。

好了,今天的基礎回顧就到這裏,順便咱們瞭解瞭如下原型設計模式,原型模式的地位很重要,它和js的原型繼承一脈相承。

後續文章更新文章請關注https://github.com/lvzhenbang/article

相關文章
相關標籤/搜索