构造函数方式
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,12);
优点,构造函数内部无创建对象,而是使用this关键字。用new运算符调用构造函数时,在执行第一行代码前先创建一个对象,只有用this才能访问该对象。然后可以直接赋予this属性,默认情况下是构造函数的返回值(不必明确使用return运算符)。
整个调试清单:
<html>
<head>
<title>closure</title>
<script type="text/javascript">
function Car(sColor, iDoors, iMpg){
this.color = sColor;
this.doors = iDoors;
this.mpg =iMpg;
this.showColor = function(){
alert(this.color);
};
}
</script>
</head>
<body>
<script>
var oCar1 = new Car("red",4, 23);
oCar1.showColor();
</script>
</body>
</html>
又一个新问题,与前面工厂函数方式一样,会重复生成函数,但可在外部函数写构造函数,并使用原型。
原型方式:
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();
看起来爱是个非常好的解决方案。遗憾的是,并非尽如人意。
首先,这个构造函数没有参数。使用原型方式时,不能通过给构造函数传递参数初始化属性的值,因为car1和car2的color属性都等于"red",doors属性都等于4,mpg属性都等于23。这意味着必须在对象创建后才能改变属性的默认值,这点很令人讨厌,但还不至于是世界末日。真正的问题出现在属性指向的对象,而不是函数。函数共享不会造成任何问题,但对象却很少被多个实例共享。考虑下面的例子:
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"
这里,属性drivers是指向Array对象的指针,该数组中包含了两个名字"Mike"和"Sue"。由于drivers是引用值,Car的两个实例都指向同一个数组。这意味着给car1.drivers添加值"Matt",在car2.drivers中也能看到。输出这两个指针中的任何一个,结果都是显示同字符串"Mike,Sue,Matt"。
由于创建对象时有这么多问题,你一定会想,是否有种合理的创建对象的方法呢?答案是联合使用构造函数和原型方式。
联合使用构造函数和原型的方式,接可以像其他程序设计语言一样创建对象。这种概念非常简单,即用构造函数定义对象的所有非函数属性,用原型方式定义对象的函数属性(方法)。结果所有函数都只创建一次,而每个对象都具有自己的对象属性实例。再重写前面的例子如下:
function Car(sColor, iDoors, iMog){
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); //outpus "Mike, Sue, Matt"
alert(oCar2.drivers); //outpus "Mike, Sue"
最后:某个朋友有幸看到此文发现有所疑惑一定是我笔记中摘录的问题,建议借《javascript高级程序设计》一书来看。