读书笔记之JavaScript的类编写方法

读书笔记之JavaScript的类编写方法

编写类一般有如下几种方法

1. 工厂函数方式(factory function)

 <script type="text/javascript">
function createCar(sColor, iDoors, iMpg) {
  var oTempCar = new Object;
  oTempCar.color = sColor;
  oTempCar.doors = iDoors;
  oTempCar.mpg = iMpg;
  oTempCar.showColor = function () {
    alert(this.color);
  };
  return oTempCar;
}

var oCar1 = createCar("red", 4, 23);
var oCar2 = createCar("blue", 3, 25);
oCar1.showColor();  //outputs "red"
oCar2.showColor();  //outputs "blue"
</script>

但以上方法有个问题,就是每次调用函数createCar()时,都会创建新函数showColor(),这意味着每个对象都有自己的showColor()版本,但事实上,每个对象都共享了同一个函数。
以下方案可以解决这个问题: 

function showColor() {
 alert(this.color);
};
function createCar(sColor, iDoors, iMpg) {
  var oTempCar = new Object;
  oTempCar.color = sColor;
  oTempCar.doors = iDoors;
  oTempCar.mpg = iMpg;
  oTempCar.showColor = showColor;
  return oTempCar;
}

var oCar1 = createCar("red", 4, 23);
var oCar2 = createCar("blue", 3, 25);
oCar1.showColor();  //outputs "red";
oCar2.showColor();  //outputs "blue"

以上黄色的部分为修改了的代码,这样就解决了重复创建函数对象的问题,但这个函数看起来不像是对象的方法,所以这个应该说也不是完美的解决方案

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);
var oCar2 = new Car("blue", 3, 25);
oCar1.showColor();  //outputs "red"
oCar2.showColor();  //outputs "blue"

这种方式应该是现在用的最多的方式了,但和工厂方法有同样的问题,就是会重复生成函数 ,当然,也可以如工厂函数方法一般将函数提到外面去再引用,这同样不完美,呵呵

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();
var oCar2 = new Car();

以上方式有两个缺陷:1. 不能通过构造函数来给对象传递参数初始化属性,必须在创建以后才能改;2. 当属性指向的是对象而不是函数时。。看下面的例子:

function Car() {
}

Car.prototype.color = "red";
Car.prototype.doors = 4;
Car.prototype.mpg = 23;
Car.prototype.drivers = new Array("Mike", "Sue");
Car.prototype.showColor = function() {
 alert(this.color);
};
var oCar1 = new Car();
var oCar2 = new Car();

oCar1.drivers.push("Matt");

alert(oCar1.drivers);  //outputs "Mike,Sue,Matt"
alert(oCar2.drivers);  //outputs "Mike,Sue,Matt"

呵呵,是不是觉得很恶?看来这种方式显然也是不对的

4. 混合构造函数/原型方式 

function Car(sColor, iDoors, iMpg) {
 this.color = sColor;
 this.doors = iDoors;
 this.mpg = iMpg;
 this.drivers = new Array("Mike", "Sue");
}

Car.prototype.showColor = function() {
 alert(this.color);
}

var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 25);

oCar1.drivers.push("Matt");

alert(oCar1.drivers);  //outputs "Mike,Sue,Matt"
alert(oCar2.drivers);  //outputs "Mike,Sue"

 呵呵,所有非函数属性都在构造函数中创建,而函数则绑定到原型上,这个就是很完美的解决方案了

5. 动态原型方法

 function Car(sColor, iDoors, iMpg) {
 this.color = sColor;
 this.doors = iDoors;
 this.mpg = iMpg;
 this.drivers = new Array("Mike", "Sue");
 
 if (typeof Car._initialized == "undefined") {
  Car.prototype.showColor = function() {
   alert(this.color);
  };
  Car._initialized = true;
 }
}

var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 25);

oCar1.drivers.push("Matt");

alert(oCar1.drivers);  //outputs "Mike,Sue,Matt"
alert(oCar2.drivers);  //outputs "Mike,Sue"

 呵呵,如何,这样就只会创建一次方法而方法又在类里面了,视觉上也要好看点

显然,最后两种方法都是推荐使用的

最后说明下,以上源代码均来自Nicholas C. Zakas的《Professional JavaScript for Web Developers》

你可能感兴趣的:(读书笔记之JavaScript的类编写方法)