JavaScript中定义类或对象


1,对象的构成

  对象有特性构成(attribute),可以是原始值,也可以是引用值。如果特性存放的是函数,它将被看做对象的方法(method),否则该特性被看做属性(property)。

  2,定义类或对象

  (1)工厂方式

    function createCar(sColor,iDoors) {
        var oTempCar = new Object;
        oTempCar.color = sColor;
        oTempCar.doors = iDoors;
        oTempCar.showColor = function() {
            alert(this.color);
        };
        return oTempCar;
    }
    var oCar1 = createCar("red",4);
    var oCar2 = createCar("blue", 3);
    oCar1.showColor(); //Output "red"
    oCar2.showColor(); //Output "blue"

  缺点:

  每次调用函数createCar()时,都要创建新函数showColor(),意味着每个对象都有自己的showColor()版本。

  改进:

    function showColor() {
        alert(this.color);
    }
    function createCar(sColor,iDoors) {
        var oTempCar = new Object;
        oTempCar.color = sColor;
        oTempCar.doors = iDoors;
        oTempCar.showColor = showColor;
        return oTempCar;
    }
    var oCar1 = createCar("red",4);
    var oCar2 = createCar("blue", 3);
    oCar1.showColor();
    oCar2.showColor();

但是该函数看起来不像对象的方法。所以就有了构造函数的出现。

  (2)构造函数方式 

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

  通常构造函数的首字母要大写。

  就想工厂函数一样,构造函数也会同样重复生成函数,为每个对象创建独立的函数版本。

  (3)原型方式

    function Car() {
    }
    Car.prototype.color = "red";
    Car.prototype.doors = 4;
    Car.prototype.showColor = function() {
        alert(this.color);
    };
    var oCar1 = new Car();
    var oCar2 = new Car();

  缺点:

  原型方式的构造函数没有参数。他不能通过传参来初始化属性的值。还有,当属性指向的是对象时,还会造成对象共享。如下: 

    function Car() {
    }
    Car.prototype.color = "red";
    Car.prototype.doors = 4;
    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);   //output "Mike,Sue,Matt"
    alert(oCar2.drivers);   //output "Mike,Sue,Matt"
(4)混合的构造函数/原型方式

    function Car(sColor, iDoors) {
        this.color = sColor;
        this.doors = iDoors;
        this.drivers = new Array("Mike", "Sue");
    }
    Car.prototype.showColor = function() {
        alert(this.color);
    };
    var oCar1 = new Car("red", 4);
    var oCar2 = new Car("blue", 3);
    oCar1.drivers.push("Matt");
    
    alert(oCar1.drivers);   //output "Mike,Sue,Matt"
    alert(oCar2.drivers);   //output "Mike,Sue

  现在就响创建一般对象一样,所有的非函数属性都在构造函数中创建,而且只创建一个showColor()函数。此外,给oCar1的drivers数组添加“Matt”值,不会影响oCar2的数组。

  因此这种方式是ECMAScript采用的主要方式。它具有其他方式的特性,却没有它们的副作用。

  (5)动态原型方式

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


  目前使用最广泛的是混合的构造函数/原型方式。此外,动态原型方式也很流行。


« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3