JavaScript中的面向对象----类
一、开篇
(以下文字一部分来自于整理的书籍内容,一部分则是总结自经验)
众所周之,JavaScript是面向对象的语言。JavaScript的对象有三种:本地对象、内置对象、自定义类的对象。
其中本地对象和内置对象都是独立于宿主由ECMAScript实现的。这里所说的本地对象和内置对象实际上跟.Net中的类的概念相似。本地对象和内置对象的区别在于本地对象在使用时要实例化,而内置对象就像所谓的静态类,可以直接使用。
JS中的本地对象有:Object Function Array String Boolean Number Date RegExp
Error等;内置对象有:Global和Math
下面着重介绍一下自定义类的五种方式:
二、在JavaScript中自定义类
1、工厂方法
function createCar(){
var oTempCar = new Object();
oTempCar.color = "red";
oTempCar.doors = 4;
oTempCar.mpg = 23;
oTempCar.showColor = function(){
alert(this.color);
}
return oTempCar;
}
var oCar1 = createCar();
oCar1.showColor();
缺点:缺点很多,基本上不会用到
2、构造函数方法
function Car(sColor,iDoors,iMpg){
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.showColor = function(){
alert(this.color);
}
}
var oCar1 = new Car("red",4,23);
oCar1.showColor();
alert(oCar1 instanceof Car);
原理:我们所谓的类还是js的一个Function而已,在Function前面用new运算符的时候,会自动创建一个object实例,并且类里面的this都指向这个object,在Function运行结束的时候,将this返回。所以其本质还是工厂方法。
优点:看起来和更像一个类 声明实例用new运算符
缺点:对象的函数会重复生成
3、原型方式
function Car(){
}
Car.prototype.color = "red";
Car.prototype.doors = 4;
Car.prototype.mpg = 23;
Car.prototype.showColor = function(){
alert(this.color);
}
var oCar1 = new Car();
oCar1.showColor();
alert(oCar1 instanceof Car);
原理:js中的prototype
优点:避免了函数的重复创建
缺点:没有带参数的构造函数 属性如果是引用类型(比如Array),那么一个对象的属性改变,另外一个对象的同一个属性也会跟着改变
4、构造函数/原型方式
function Car(sColor,iDoors,iMpg){
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
}
Car.prototype.showColor = function(){
alert(this.color);
}
var oCar1 = new Car("red",4,23);
oCar1.showColor();
alert(oCar1 instanceof Car);
优点:避免了函数的重复创建 并且避免了构造函数方法的引用类型属性的缺点
缺点:方法在类的外边定义的
5、动态原型方式
function Car(sColor,iDoors,iMpg){
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
if(typeof Car._initialized == "undefined"){
Car.prototype.showColor = function(){
alert(this.color);
}
Car._initialized = true;
}
}
var oCar1 = new Car("red",4,23);
oCar1.showColor();
alert(oCar1 instanceof Car);
原理:Car也可以有属性的 通过_initialized这个标志确保方法只被声明一次
优点:避免了函数的重复创建 属性和方法都写在类的定义里
缺点:
三、我所使用的类
1、关于私有变量:
JavaScript中,基本上没法区分私有变量和公共变量,但是可以在命名上区分,一般习惯在私有变量的前后各加上两个下划线 this.__privatePropery__或者是在变量前加一个下划线this._privateProperty。
2、从构造函数方法衍生
对于第二种方法——构造函数方法对于私有变量的处理却有很大的优势!它可以将私有变量做到与外部隔离。这种隔离是将私有变量和方法在类里面用var来声明,而共有的变量和方法用赋值给this。
例子如下:
function Car(sColor,iDoors,iMpg){
var self = this;
this.color = sColor;
this.doors = iDoors;
var mpg = iMpg;//私有变量
this.showCarInfo = function(){
alert(this.color);
alert(mpg);//不是this.mpg
}
var privateShowCarInfo = function(){
//这时只能访问私有变量
//alert(this.color);//会出错
alert(mpg);//可以访问
//那怎么才能访问this.color呢?总不可能私有方法不能访问公共属性吧?
//在类里面设置一个私有变量,让他指向这个实例//第二行中var self = this;
alert(self.color);//调用成功//当然 公共方法也能访问self
}
this.anotherShowCarInfo = function(){
privateShowCarInfo();
}
}
var oCar1 = new Car("red",4,23);
oCar1.showCarInfo();
oCar1.anotherShowCarInfo();
alert(oCar1 instanceof Car);
总之:this.方法能访问this.属性和var 变量
Var方法只能访问var变量,需要借助self变量来访问this.属性
这样的话显得更面向对象了,但是构造函数方法的老毛病还是没有改掉,对象的函数还是会被重复创建,但是我相信在一般情况下这对性能构不成威胁的。
四、示例下载