標籤:
在javascript中是支援物件導向編程的,講到物件導向(Object Oriented簡稱為OO)一般很容易想到繼承和多態,而在javascript中呢,繼承主要是靠原型鏈作為主要方法去實現的。其基本思想是利用原型讓一個參考型別繼承另一個參考型別的屬性和方法。
來看一段代碼:
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屬性,這個屬性是一個指標,指向了一個原型對象,原型對象就是用來包含所有執行個體對象共用的屬性和方法
·在預設的情況下呢,原型對象會自動獲得一個constructor(建構函式)屬性,這個屬性包含了一個指向建構函式的指標
·而通過調用建構函式產生的執行個體對象,它們都包含了一個指向原型對象的內部指標,叫做__proto__
簡單地畫了一個圖方便理解:
我們去瀏覽器列印出來看一看,是不是所說那樣
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
原型鏈細分點展開來講還是有許多地方可以去探討的,這篇就先寫到這吧
以上,是我對原型鏈的個人理解,文中如有錯誤,歡迎大家指正:)
淺談JavaScript原型鏈