深刻探究JavaScript对象系列(五)

       以前比较忙,再加上家里发生了些不开心的事情,也就没什么心情看书,昨天加了一天班,今天终于能够静下心来写点东西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

二.constructor属性

  先看下下面这张图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

相关文章
相关标签/搜索