以前比較忙,再加上家裏發生了些不開心的事情,也就沒什麼心情看書,昨天加了一天班,今天終於能夠靜下心來寫點東西html
在JavaScript中,類的全部實例對象都從同一個原型對象上繼承屬性,所以原型對象是類的核心,這個在以前幾篇中已經提到過,如今咱們來看兩個例子,着兩個例子實現了一樣的效果:函數
1 例一: 2 function inherit(p){ /;/這個函數是用來建立對象的,以前已經寫到過了 3 if(p == null) throw TypeError(); 4 if(Object.create) return Object.create(p); 5 6 var t = typeof p; 7 if(t !== "object" && t !== "function") throw TypeError(); 8 function F(){}; 9 f.prototype = p; 10 return new F(); 11 } 12 13 range.methods = { 14 includes : function(x){ 15 return this.from <= x && x <=this.to; 16 }, 17 18 toString : function(){ 19 return "this is form "+this.from+" to "+this.to; 20 } 21 } 22 23 function range(from,to){ 24 var r = inherit(Range.methods); 25 r.from = from; 26 r.to = to; 27 return r; 28 } 29 var r = range(1,9);
r.includes(3); //返回true 30 //例二 31 function Rnage(from,to){ 32 this.from = from; 33 this.to = to; 34 } 35 36 Range.prototype = { 37 includes : function(x){ 38 return this.from <= x && x <=this.to; 39 }, 40 41 toString : function(){ 42 return "this is form "+this.from+" to "+this.to; 43 } 44 }
var r = new Range(1,9);
r.includes(22);//返回false
上述兩個例子實現了一樣的效果,例一中定義了一個工廠方法range(),用來建立新的範圍對象,要注意的地方是range函數給每一個範圍對象都定義了from屬性和to屬性,這兩個屬性是非共享的,固然也是不可繼承的。(用這種方式來建立新對象的方法不常見)測試
例二中使用瞭如今常常看到的利用構造函數來建立對象的方法,調用構造函數的一個重要特徵是,構造函數的prototype屬性被用來作新對象的原型。this
原型對象是類的惟一標誌:當且僅當兩個對象繼承自同一個原型對象時,他們才屬於同一個類的實例,舉個例子來講,當使用instanceof來檢測一個對象是否爲給定類的實例時,如r instanceof Range,js引擎不是檢查r是不是由Range()函數來建立,而是檢查r的原型對象是否是Range.prototype.spa
先看下下面這張圖prototype
任何一個JavaScript函數均可以用來看成構造函數(但每每不會正常工做),而且調用一個構造函數是要用到函數的prototype函數的,所以除了ECMAScript5中的Function,bind()方法返回的函數外,每個js函數都自動擁有一個prototype屬性,這個屬性也是一個對象包含一個惟一不可枚舉的constructor屬性,這個屬性的值是一個函數對象(var F = function(){};),js正式用這個屬性來只帶它們的構造函數,用代碼的方式來表現就是像下面這個樣子3d
1 var p = F.prototype; 2 var c = p.constructor; 3 c === F; //返回true
或者是像下面這樣:code
1 function F(){}; 2 var o = new F(); 3 o.constructor === F; //返回true
可能會有人拿上一節中的例二來測試constructor,結果發現是不對的,爲何不對呢?那是由於例二中Range.prototype被重寫了,它根本就沒有constructor屬性,那怎麼補救呢,很簡單,能夠這樣寫:orm
1 //方法一 2 Range.prototype = { 3 constructor : Range, //顯式地指定constructor值 4 includes : function(x){ 5 return this.from <= x && x <=this.to; 6 }, 7 8 toString : function(){ 9 return "this is form "+this.from+" to "+this.to; 10 } 11 } 12 13 //方法二 14 Range.prototype.includes = function(x){ 15 return this.from <= x && x <=this.to; 16 } 17 Range.prototype.toString = function(x){ 18 return "this is form "+this.from+" to "+this.to; 19 }
關於原型繼承和constructor,推薦你們看看這個http://www.cnblogs.com/sanshi/archive/2009/07/08/1519036.html,看完會有更深的理解。htm