JavaScript定义类的方法总结

发布时间:2021-01-13编辑:脚本学堂
本文介绍下javascript中定义类的多种方法,要学好javascript,面向对象这块是不能少的,建议大家好好掌握。

javascript中定义类的各种方法。

1.工厂方式
javaScript中创建自己的类和对象,javaScript中对象的属性可以在对象创建后动态定义。

例如:
 

复制代码 代码示例:
<script type="text/javascript">
    //定义
    var oCar = new Object();
    oCar.color = "red";
    oCar.doors = 4;
    oCar.showColor = function() {
        alert(this.color);
    }
    //调用
    oCar.showColor();
</script>

很容易使用oCar对象,但是想要创建多个Car实例。
可以使用一个函数来封装上面的代码:
 

复制代码 代码示例:
<script type="text/javascript">
    //定义
    function createCar() {
        var oCar = new Object();
        oCar.color = "red";
        oCar.doors = 4;
        oCar.showColor = function() {
   alert(this.color);
        }
        return oCar;
    }
    //调用
    var ocar1 = createCar();
    var ocar2 = createCar();
    ocar1.color = "black";
    ocar1.showColor();
    ocar2.showColor();
</script>

javaScript对象默认成员属性都是public 的。

这种方式称为工厂方式,创造了能创建并返回特定类型的对象的工厂。

但是在面向对象中 经常使用创建对象的方法是:
Car car=new Car();
使用new 关键字已经深入人心,因此使用上面的方法去定义总感觉别扭,并且每次调用时都去创建新的属性以及函数,功能上也不实际。

接下来看看构造函数的形式定义类。

2.构造函数
这种方式看起来有点象工厂函数。

具体如下:
 

复制代码 代码示例:
<script type="text/javascript">
    //定义
    function Car(color, doors) {
        this.color = color;
        this.doors = doors;
        this.showColor = function() {
   alert(this.color);
        };
    }
    //调用
    var car1 = new Car("red", 4);
    var car2 = new Car("blue", 4);
    car1.showColor();
    car2.showColor();
</script>

在构造函数内部创造对象使用this 关键字,使用new 运算符创建对象感觉非常亲切。

问题:每次new 对象时都会创建所有的属性,包括函数的创建,也就是说多个对象完全独立,定义类的目的就是为了共享方法以及数据,但是car1对象与car2对象都是各自独立的属性与函数,最起码 应该共享方法。这就是原形方式的优势所在。

3.原型方式
利用对象的prototype属性,可把它看出创建新对象所依赖的原型。

方法如下:
 

复制代码 代码示例:
<script type="text/javascript">
    //定义
    function Car() {
    };
    Car.prototype.color = "red";
    Car.prototype.doors = 4;
    Car.prototype.drivers = new Array("Tom", "Jerry");
    Car.prototype.showColor = function() {
        alert(this.color);
    }
    //调用:
    var car1 = new Car();
    var car2 = new Car();
    car1.showColor();
    car2.showColor();
    alert(car1.drivers);
    car1.drivers.push("stephen");
    alert(car1.drivers); //结果:Tom,Jerry,stephen
    alert(car2.drivers); //结果:Tom,Jerry,stephen
 
//可以用json方式简化prototype的定义:
        Car.prototype =
        {
   color: "red",
   doors: 4,
   drivers: ["Tom", "Jerry",'safdad'],
   showColor: function() {
       alert(this.color);
   }
        }
</script>

首先,这段代码的构造函数,其中没有任何代码,接下来通过对象的prototype属性添加属性定义Car对象的属性。

问题是Car的对象指向的是Array指针,Car的两个对象都指向同一个Array数组,其中一个对象car1改变属性对象的引用(数组Array)时,另一个对象car2也同时改变,这是不允许的。
同时该问题也表现在原型不能带任何初始化参数,导致构造函数无法正常初始化。

这需要另一种方式来解决:那就是混合的构造函数/原型模式。

4. 混合的构造函数/原型模式
联合使用构造函数和原型方式,定义类就非常方便。
 

复制代码 代码示例:

<script type="text/javascript">
//定义
    function Car(color,doors)
   {
        this.color=color;
        this.doors=doors;
        this.drivers=new Array("Tom","Jerry");
   }
   Car.prototype.showColor=function(){
        alert(this.color);
   }

   //调用:
   var car1=new Car('red',4);
   var car2=new Car('blue',4);

   car1.showColor();
   car2.showColor();

   alert(car1.drivers);
   car1.drivers.push("stephen");
   alert(car1.drivers); //结果:Tom,Jerry,stephen
   alert(car2.drivers); //结果:Tom,Jerry
   alert(car1 instanceof Car);
</script>

该方法是把属性放在内部定义,把方法放在外边利用prototype进行定义。解决了第三种方法的问题。

比起java的语法来,应该有一些不和谐,感觉比较凌乱,对C++来说, 就没有那么麻烦的感觉了,可是开发C++的研发人员一般情况下很少涉及javaScript,而对J2EE的研发人员来说,这种方式总有一些别扭。

总感觉不是友好的封装,其实只不过是视觉上封装效果不是很好而已,要想达到视觉封装效果而又能达到这种方法的效果的也可以以,个人认为其实比较麻烦。那就是动态原型法。