Javascript面向對象編程

https://segmentfault.com/a/1190000002900676javascript

 

介紹

和java這種基於類(class-base)的面向對象的編程語言不一樣,javascript沒有類這樣的概念,可是javascript也是面向對象的語言,這種面向對象的方式成爲 基於原型(prototype-base)的面向對象。雖說ES6已經引入了類的概念來做爲模板,經過關鍵字 「class」 能夠定義類,但ES6的這種寫法能夠理解爲一種語法糖,它的絕大部分功能,ES5均可以作到,新的class寫法只是讓對象原型的寫法更加清晰、更像面向對象編程的語法而已。若是要理解基於原型實現面向對象的思想,那麼理解javascript中得三個重要概念: 構造函數(constructor)、原型(prototype)、原型鏈(prototype chain) 對幫助理解基於原型的面向對象思想就顯得尤其重要。下面就重點介紹一下這幾個概念。java

javascript對象結構圖

先來看一張來自mollypages.org 的javascript對象的結構圖,下面的例子都按照這張圖闡述。編程

構造函數(constructor)和原型 (prototype)

構造函數是用來初始化對象的,每一個構造函數都有一個不可枚舉的屬性,這就是原型(prototype).而且,每一個prototype 都包含一個包含了不可枚舉屬性的constructor屬性,這個屬性始終會指向構造函數。segmentfault

function Foo(){}; console.log(Foo.prototype.constructor === Foo); // true 

原型鏈(prototype chain)

使用new實例化的原型

每一個被new實例化的對象都會包含一個__proto__ 屬性,它是對構造函數 prototype 的引用。編程語言

function Foo(){}; var foo = new Foo(); console.log(foo.__proto__ === Foo.prototype); // ture 
function Foo(){}; console.log(Foo.prototype.__proto__ === Object.prototype); // true 

上面返回true 的緣由是Foo.prototype 是Object預建立的一個對象,是Object建立的一個實例,因此,Foo.prototype.__proto_ 是Object.prototype的引用。函數

咱們能夠來看一下原型鏈的脈絡。ui

函數(function)對象的原型

在javascript中,函數是一種特殊的對象,全部的函數都是構造函數 Function 的實例。spa

function Foo() {}; console.log(Foo.__proto__ === Object.prototype); //false console.log(Fool.__proto__ === Function.prototype); // true 

從上面能夠看出,函數Foo.__proto_ 指向到 Function.prototype, 說明函數 Foo 是 Function的一個實例。prototype

function Foo(){}; console.log(Foo.__proto__ === Function.prototype); //true console.log(Foo.prototype.__proto__ === Object.prototype);//true 

Foo.prototype 是Object預約義的對象,構造函數爲Object,因此__proto__指向 Object.prototypecode

從上面的圖咱們能夠看出, Object、Function、Array 等這些函數,他們的構造函數都是 Function 的實例。

基於原型鏈的繼承

有了上面的基礎知識之後,咱們就能夠本身去基於原型鏈去封裝對象,實現javascript的繼承。先來看下面一個例子。

運行上面的例子,輸入 cat init 和 animal eat,說明cat 繼承了 Animal.prototype.eat 的方法。

咱們來分析一下代碼。

一、Animal 的prototype中定義了 eat方法。
二、將Empty.prototype 指向 Animal.prototype , 因此 Empty.prototype 中也存在eat方法.
三、Cat.prototype == new Empty(),因此 Cat.prototype.__proto_ === Animal.__proto_.
四、從新爲Cat指定constructor爲Cat,不然Cat不存在constructor。

這樣就完成了繼承,原型鏈是這樣的:

這樣咱們用原型鏈的方式實現了一個簡單的繼承方式。

相關文章
相關標籤/搜索