日期:2014-05-16  浏览次数:20464 次

javascript_创建类和对象_小结

javascript中的类和对象创建方式

?

一、构造函数+原型方式

创建一个对象,构造函数是最直接的方式了,不论对编译型的java还是解释型的ruby,都用new来创建对象。javascript也可以用new来创建。

例子:

        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();
        oCar2.showColor();

因为javascript中的函数也是一个对象,这种方式就导致了一个问题:每new一个对象,就重复创建一个一模一样的“方法对象”。

因为方法也是一个对象(方法对象),那么可否在构造函数里再增加一个参数呢?可以,如下。这种方式有点儿ruby的味道了(传递一个方法),但是这不符合习惯(方法在类内建立),也不符合科学(建立很多方法总不能这么传递进去吧)。接着往下看。

        showColor = function () {
            alert(this.color);
        };
        function Car(sColor, iDoors, iMpg, fnShowColor) {
            this.color = sColor;
            this.doors = iDoors;
            this.mpg = iMpg;
            this.showColor = fnShowColor
        }
        var oCar1 = new Car("red", 4, 23, showColor)
        var oCar2 = new Car("blue", 3, 25, showColor)
        oCar1.showColor()
        oCar2.showColor()

进一步的解决方式是,利用javascript的prototype属性,可以让所有new的对象“继承”同一个方法。

这种方式遗留的一个缺点是不好看:一个函数定义在了类之外。

//用构造方法设置属性,用原型方法设置函数(因为函数是共享的)
        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"
?

二、动态的原型方式

?

        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;
            }
        }

似乎这种方式最完美,不过也引入了额外的判断代码。

注意:Car是构造方法,javascript中方法是对象,对象可以有属性,而且可以动态添加。这个_initialized属性就是这么来的。

?

三、工厂方式(很少使用)

工厂方式就是在工厂内new一个Object,之后把工厂方法的参数赋给这个对象。

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 oCar1 = createCar(“blue”, 3, 25);
oCar1.showColor(); //outputs “red”
oCar2.showColor(); //outputs “blue”

这种方式也有重复建立方法的问题。一个改进如下,但更让代码难看。

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”

?综合来看,这种方式适合做框架用,但不如前两种易于理解和使用(没关)。

?

+——

+——

+——

)顺便说一句,javaeye或iteye这个编辑器真难用,老出现下面的乱码。真是受不了了。<