Javascript 物件導向中的建構函式和原型物件

weixin_34221276發表於2015-06-19

先解釋下原型。每一個Javascript物件(null除外)都和另外一個物件相關聯,這個“另外一個物件”就是我們熟知的原型, 每一個物件都從原型繼承屬性和行為(方法)。

var   a = {}; //原型物件為Object.prototype
var   array = new Array()// 原型物件為Array.prototype
var   myInstance = new MyClass;// 原型物件為MyClass.prototype

在Javascript中,類的所有例項物件都從同一個原型物件上繼承屬性,下面先看一個例子

function Range是 Range類的建構函式用以初始化新建立的Range類的物件,建構函式並沒有建立並返回一個物件,僅僅是初始化,並且在建構函式中用this設定的屬性不是每個例項共享的,而是獨享的,this是對當前物件的應用。

function Range(from, to) {
          if(from)
               this.from = from;//物件的自有屬性,在物件中會覆蓋從原型那裡繼承來的from值
          if(to)
               this.to = to; 
}

而所有物件例項都會繼承的屬性和行為(方法)都在原型物件裡

Range.prototype = {
     includes : function(x) {return this.from <= x && x <= this.to},
     
     foreach : function(f) {
           for(var x = Math.ceil(this.form); x < this.from; x++)  f(x);
    },
    
    toString : function() {return "(" + this.from + "......" + this.to + ")";},
    
    from : 1,

    getBeginning : function() {return this.from}
}
var r = new Range(2, 5);
r.include(3);// true , 3在範圍內
r.foreach(alert);//輸出2 3 4 5
console.log(r)//
r.getBeginng() // 2 因為在建構函式初始化r的時候已經把屬性“from”設定成2了

任何Javascript函式都可以做建構函式,並且用new 關鍵字呼叫建構函式時是要用到一個prototype屬性的。因此每個javascript函式都會自動擁有一個prototype屬性。比如

Range.prototype.init = function () {}
nr = new Range.prototype.init();// nr 的屬性繼承自Range.prototype.init.prototype

原型物件是類的唯一標示,當且僅當兩個物件繼承自同一個原型物件時,他們才是屬於同一個類的例項,而初始化物件的建構函式則不能作為類的標示。 兩個建構函式的prototype屬性可能指向同一個原型物件,這時通過new呼叫兩個建構函式建立的例項是屬於同一個類的。

上面的例子繼續修改

Range.prototype.init.prototype = Range.prototype;//引用傳遞所以不用擔心迴圈引用;

這樣通過new Range()和 new Range.prototype.init()建立的物件都是屬於Range類的。

console.log((r instanceof Range)); //true
console.log((nr instanceof Range)); //true

相關文章