首先,我们必须要理解所有的对象都是一种引用。
一 定义类或对象
1 工厂方式
function createCar()
{
var oTmepCar = new Object;
oTmepCar.color="red";
oTmepCar.doors = 4;
oTmepCar.mpg = 23;
oTmepCar.showColor = function(){
alert(this.color);
}
return oTmepCar;
}
2 构造函数模式
function Car(sColor,iDoors,iMpg)
{
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.showColor = function(){
alert(this.color);
}
}
这两种方式都是重复生成function函数,当然可通过定义外部function添加引用来解决这个问题,但是在语义上无任何意义。
3 原型方式
function Car()
{
car.prototype.color ="red";
car.prototype.doors = 4;
car.prototype.mpg = 23;
car.prototype.showColor = function()
{
alert(this.color);
}
}
使用这种方式可以解决前面的重复生成函数的问题,而且还能用instanceof运算符检查给定变量指向的对象的类型。
缺点:这个构造函数没有参数,另外真正的问题在于属性指向的是对象,而不是函数。
as:Car.prototype.drivers = new Array("lin","tiw");
当是实例car1给drivers赋值car1.drivers.push("frankie");
那么这时候如果有car2的时候,那么car2的drivers就变成了"lin","tiw","frankie";
4 混合的构造函数/原型方式
function Car(sColor,iDoors,iMpg)
{
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("lin","tiw");
}
Car.prototype.showColor = function(){
alert(this.color);
}
现在就更像创建一般对象了。所有的非函数属性都在构造函数中创建,意味着又可用构造函数的参数赋予属性默认值。因为只创建一个function函数的一个实例,所以没有浪费内存。
二 继承
1 对象冒充
2 call()
3 apply()
4 原型链
function ClassSon(){}
ClassSon.prototype = Car;(这是错误的,因为Car类的构造参数有参数,这只是一种参考,请查看下面的参考。)
这样ClassSon就继承了Car类的属性和方法。
注意:调用Car的构造函数时,没有给它传递参数,这在原型链中试标准做法,要确保构造函数没有任何参数。