1.类和构造函数
使用关键字new调用构造函数会自动创建一个新对象,构造函数本身只需初始化这个新对象的状态即可。调用构造函数的一个重要特征是,构造函数的prototype属性被用做新对象的原型。这意味着通过同一个构造函数创建的所有对象都继承自一个相同对象,因此它们都是同一个类成员。
//这是一个构造函数,用以初始化新创建的对象
//注意,这里并没有创建并返回一个对象,只是初始化
function Range(from,to){
//这2个属性是不可继承的,每个对象都拥有唯一的属性
this.from=from;
this.to=to;
}
//所有的对象都继承自这个对象
//注意,属性的名字必须是prototype
Range.prototype={
includes:function(x){
return this.from<=x && x<=this.to;
}
};
var r=new Range(1,3);//创建一个新对象
r.includes(2);//true,2在范围内
alert(r.from);//对象中的属性
常规的编程约定:从某种意义上讲,定义构造函数即是定义类,并且类名首字母要大写。而普通的函数和方法都是首字母小写。
如果要判断某个对象是否是某个对象的实例的话,可以用
r instanceof Range
constructor属性
每个javascript函数都自动拥有一个prototype属性,这个属性的值是一个对象,这个对象包含唯一一个不可枚举属性constructor,它的值是一个函数对象:
var F=function(){};//这是一个函数
var p=F.prototype;//这是F相关联的原型对象
var c=p.constructor;//这是与原型相关联的函数
c===F;//true,对于任意函数F.prototype.constructor=F
可以看到构造函数中原型中存在预先定义好的constructor属性,这意味着对象通常继承的constructor均指它们的构造函数。由于构造函数是类的“公共标识”,因此这个constructor属性为对象提供了类:
var o=new F();//创建类F的一个对象
o.constructor===F;//constructor属性指代这个类
下图展示了构造函数和原型对象之间的关系,包括原型到构造函数的反向引用以及构造函数创建的实例
注意如果使用Range.prototype={}的方式,那么就会重写预定义的Range.prototype对象。这个新定义的原型对象不含有constructor属性,因此Range类的实例也不含有
constructor属性。可以给原型显式添加一个构造函数:
Range.prototype={
constructor:Range,//显式设置构造函数反向引用
includes:function(x){
return this.from<=x && x<=this.to;
}
};
如果依次给原型对象添加方法,则不会破坏原来原型中的constructor属性
var F1=function(){};
F1.prototype.add=function(){};
当然如果觉的这样写分散了,可以使用下面的方式:
//通过继承的方式,来为prototype添加属性
function extend(destination,source){
for(var property in source){
destination[property]=source[property];
}
}
var F1=function(){};
extend(F1.prototype,{add:function(){}});
F1.prototype