在javascript中是支持面向對象編程的,講到面向對象(Object Oriented簡稱爲OO)通常很容易想到繼承和多態,而在javascript中呢,繼承主要是靠原型鏈做爲主要方法去實現的。其基本思想是利用原型讓一個引用類型繼承另外一個引用類型的屬性和方法。javascript
來看一段代碼:java
function Animal(name,color){ this.name = name; this.color = color; } Animal.prototype.type = "動物"; Animal.prototype.msg = function(){ alert( "I am "+this.name+" my color is "+this.color); } var cat = new Animal("cat","black"); alert(cat.name); //cat alert(cat.color); //black
alert(cat.type); //動物
cat.msg(); //I am cat my color is black
函數Animal就是一個構造函數,對象cat是經過new Animal()產生的一個實例對象,這個cat實例對象就繼承了構造函數Animal的name、color屬性了,這種叫作構造函數模式編程
在背後是如何實現繼承的呢?瀏覽器
這裏有三個概念:構造函數(函數Animal)、原型對象(Animal.prototype)、實例對象(對象cat)函數
·建立的每個函數都有一個prototype屬性,這個屬性是一個指針,指向了一個原型對象,原型對象就是用來包含全部實例對象共享的屬性和方法this
·在默認的狀況下呢,原型對象會自動得到一個constructor(構造函數)屬性,這個屬性包含了一個指向構造函數的指針spa
·而經過調用構造函數產生的實例對象,它們都包含了一個指向原型對象的內部指針,叫作__proto__prototype
簡單地畫了一個圖方便理解:指針
咱們去瀏覽器打印出來看一看,是否是如圖所說那樣對象
console.log(animal.prototype);
constructor是指向了原來的構造函數Animal,而且是包含了type屬性和msg方法的
console.log(cat);
實例對象cat的__proto__是指向了原型對象的,也正是靠它實現了繼承原型對象包含的屬性和方法的
在這個過程當中會發現一個有意思的事情,會看到原型對象裏面也有個__proto__內部指針,指向的是Object對象,全部的對象最終都會經過__proto__指針指向到Object的,再回頭去理解原型「鏈」這個概念,仍是挺形象的
幾種繼承方式:
·組合式繼承
function SuperType(){
this.friends = ['tom','jason','pual']; } function SubType(age){ SuperType.call(this); //使用call,借用sup構造函數 this.age = age; } SubType.prototype = new SuperType(); //修改sub原型對象等於super的實例
SubType.prototype.constructor = SubType; //讓sub的原型對象constructor指針指向構造函數
sub var x = new SubType('20');
x.friends.push('jack');
alert(x.friends); //tom,jason,pual,jack
·原型式繼承
var person = { name : 'x', age : 20, friend : ['tom','jason','pual'] } var anotherPerson = Object(person); anotherPerson.friend.push('jack'); alert(anotherPerson.friend); //tom,jason,pual,jack
·寄生組合繼承
function SuperType(name){ this.name = name; } SuperType.prototype.sayName = function(){ alert('my name is ' + this.name); } function SubType(name,age){ SuperType.call(this,name); this.age = age; } function inheritPrototype(subType,superType){ var prototype = Object(superType.prototype); //新建prototype對象指向super的原型對象 prototype.constructor = subType; //修改constructor指向構造函數sub subType.prototype = prototype; //修改sub的原型對象指向prototype } inheritPrototype(SubType,SuperType); var x = new SubType('x'); alert(x.name); //x x.sayName(); //my name is x
原型鏈細分點展開來說仍是有許多地方能夠去探討的,這篇就先寫到這吧
以上,是我對原型鏈的我的理解,文中若有錯誤,歡迎你們指正:)