每次遇到JS面對對象這個概念,關於繼承及原型,腦海裏大概有個知識框架,可是很不繫統化,複習下,將其系統化,內容涉及到對象的建立,原型鏈,以及繼承。框架
兩種經常使用方式,其他的比較少見
工廠模式:函數
function createObject(){ var o = {} o.name = "Nico" o.age = 8 o.sayName = function(){ alert(this.name) } return o }
這種方式比較不開門見山,比較直接的事第二種,構造函數方式this
function Object(name, age){ this.name = name this.age = age this.sayName = function(){ alert(this.name) } }
一般使用第二種,比較直觀
考慮到函數也是對象的一種,每次對象的實例化中其方法也會跟隨着實例化一次,爲了解決這個問題,所以出現了組合構造原型模式,這是最經常使用的一種方式。spa
組合構造原型模式prototype
function Object(name, age){ this.name = name this.age = age } Object.prototype.sayName = function(){ alert(this.name) }
將自身屬性於構造函數中定義,公用的方法綁定至原型對象上指針
原型對象的解釋
每個函數建立時自己內部會有一個固有的原型對象,能夠經過 函數名.prototype 去訪問,而其原型對象又有一個屬性constructor指針指向該函數。
假設有一個構造函數code
function Person(){ this.name = "Nicholas" this.age = 29 this.job = "Software Engineer" } Person.prototype.sayName = function(){ alert(this.name) } var person1 = new Person() var person12 = new Person()
其原型對象、構造函數、實例之間的關係以下對象
構造函數能夠經過Person.prototype來訪問原型對象,可是實例是沒有辦法來訪問原型對象的,可是在Firefox、Chrome、Safari的每個實例對象都有一個_proto_的屬性進行訪問其原型繼承
原型鏈:
根據以上的原型關係能夠發現,實例先從自身定義的屬性及方法中取值,若沒法尋找到,則向上一級即原型對象訪問須要的屬性及方法,若其原型對象是另外一個對象的實例,仍沒法訪問到屬性與方法的話,再繼續向該實例的原型對象訪問,這樣就構成了一個原型鏈,也是繼承的實現方式。圖片
有以下兩個對象
function SuperType(){ this.property = true } SuperType.prototype.getSuperValue = function(){ return this.property } function SubType(){ this.subproperty = false } SubType.prototype = new SuperType() SubType.prototype.getSubValue = function(){ return this.subproperty } var instance = new SubType() alert(instance.getSubValue()) // false
這是一個簡單的繼承實現方式,子類SubType具備了父類的property屬性,同時也具備getSubValue的方法。
其原型鏈以下:
可是這樣作會將父類的屬性綁定至子類的原型上,若是父類具備按引用訪問的數據時,子類的某一個實例中該數據的變化會致使全部子類實例該數據的變化,所以改進爲借用構造函數模式的繼承
function SubType(){ SuperType.call(this) this.subproperty = false }
這樣就解決了該問題,將property屬性定義在了子類構造函數上,子類實例訪問時先從該自己構造函數具備的屬性中進行訪問,且進行操做,至關於覆蓋了原型上的該同名屬性。
可是上述的方法又出現了一個別的問題,該問題也比較容易解決,比較少用到,筆記先到這,後續筆記將記錄該問題及解決辦法