在javascript中,类的所有实例对象都从同一个原型对象上继承属性,因此原型对象是类的核心。
为了方便说明原型继承,我们先定义一个函数来负责通过原型继承创建一个新对象
function inherit(p){
if(p==null) throw TypeError(); //p是一个对象,但不能是null
if(Object.create) return Object.create(p);
//如果Object.create()存在,直接使用它
var t=typeof p; //否则进一步检测
if(t!=="object" && t!=="function") throw TypeError();
function f(){}; //定义一个空的构造函数
f.prototype = p; //将其原型设置为P
return new f(); //使用f()创建p的继承对象
}
上面定义了一个inherit()函数,这个函数返回一个新创建的继承自P的对象。如果定义一个原型对象p,然后通过inherit()函数创建一个继承自p的对象,这样就定义了一个javascript类。
通常,类的实例还需要进一步初始化,通常通过定义一个函数来创建并初始化这个新对象;
下面给一个表示“值得范围”的类定义了原型对象,还定义一个“工厂”函数用以创建并初始化类的实例
原型对象定义方法,这些方法为每个范围对象所继承
range.methods={
includes:function(x){return this.from <=x && x<=this.to;},
foreach:function(f){//这个方法对范围内的每个整数都调用一次f
for(var x=Math.ceil(this.from);x<this.to;x++) f(x)
},
toString:function(){return "("+this.from+"..."+this.to+")"}
}
定义一个工厂方法,返回一个新的范围对象
function range(from,to){
var r=inherit(range.methods);
r.from=this.from;
r.to=this.to;
return r;
}
实例化范围对象
var r=range(1,3); //注意:这里对的r和range中的r是两回事
r.includes(2) //true
r.foreach(console.log) //1 2 3
1、以上这一段代码定义了一个工厂方法range(),用来创建新的范围对象,我们应该注意到,这里给range()函数定义了一个属性range.methods,用以快捷地存放定义类的原型对象(把原型对象挂载到函数对象上并不是惯用的做法)
2、注意range()函数给每个范围对象都定义了from和to属性,用于定义范围的起始位置和结束位置,这两个属性是非共享的,当然也是不可继承的
3、注意在range.methods中定义的那些可共享的、可继承的方法都用到了from和to属性,而且还是用了this关键字,使用this关键字来指代调用这个方法的对象,
4、任何类的方法都可以通过this的这种基本方法来读取对象的属性
期阅读你下一篇博文,关于使用构造函数来创建类【09类和模块】——2类和构造函数