对象
对象的创建方式是用关键字 new 后面跟上实例化的类的名字,定义对象名字需要大写,没有参数的话后面括号可以省略
创建对象var obj = new obj();
废除对象obj = null;
构造函数
- 工厂方式
function createCar() {
var oTempCar = new Object;
oTempCar.color = "blue";
oTempCar.doors = 4;
oTempCar.mpg = 25;
oTempCar.showColor = function() {
alert(this.color);
};
return oTempCar;
}
var oCar1 = createCar();
var oCar2 = createCar();
缺点:用这种方式必须创建对象的方法。每次调用函数 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;
}
- 构造函数方式
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);
缺点:构造函数也会重复生成函数,为每个对象都创建独立的函数版本
- 原型方式
function Car() {
}
Car.prototype.color = "blue";
Car.prototype.doors = 4;
Car.prototype.mpg = 25;
Car.prototype.showColor = function() {
alert(this.color);
};
var oCar1 = new Car();
var oCar2 = new Car();
缺点:
1.这个构造函数没有参数,不能通过给构造函数传递参数来初始化属性的值
2.属性指向的是对象,而不是函数,对象共享造成属性值不能随意改变
综上所述推荐使用混合方式
- 混合的构造函数/原型方式
用构造函数定义对象的所有非函数属性,用原型方式定义对象的函数属性(方法)。结果是,所有函数都只创建一次,而每个对象都具有自己的对象属性实例。
function Car(sColor,iDoors,iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("Mike","John");
}
Car.prototype.showColor = function() {
alert(this.color);
};
var oCar1 = new Car("red",4,23);
var oCar2 = new Car("blue",3,25);
oCar1.drivers.push("Bill");
alert(oCar1.drivers); //输出 "Mike,John,Bill"
alert(oCar2.drivers); //输出 "Mike,John"
js继承机制实现
call()方法
ClassA.call(obj, sColor);
第一个参数是 对象,第二个是函数要传的参数
此行代码的意思是把对象ClassA的属性和方法继承给obj对象apply()方法
ClassA.apply(this, arguments);
第一个参数仍是 obj,第二个参数可以把 ClassB 的整个 arguments 对象作为第二个参数传递给 apply() 方法
原型链继承
function ClassA(sColor) {
this.color = sColor;
}
ClassA.prototype.sayColor = function () {
alert(this.color);
};
function ClassB(sColor, sName) {
ClassA.call(this, sColor);//在 ClassB 构造函数中,用对象冒充继承 ClassA 类的 sColor 属性
this.name = sName;
}
ClassB.prototype = new ClassA();//用原型链继承 ClassA 类的方法
ClassB.prototype.sayName = function () {
alert(this.name);
};