• Javascript定义类或对象


    使用预定义对象的能力只是面向对象语言的能力的一部分,它真正强大之处在于能够创建自定义的类和对象.有以下几种创建方式:

    1.工厂方式

    我们可以这样定义一辆车:

            var car1 = new Object;
            car1.color='red';
            car1.doors=4;
            car1.showColor=function(){
                return this.color;
            }
    此时,我们创建了一辆车,但是,当我们想创建第二辆,第三辆车时,该如何写呢?再写一遍类似重复的代码?不是,此时我们就可以使用工厂方式:
            function CreateCar(){
                var car1 = new Object;
                car1.color='red';
                car1.doors=4;
                car1.showColor=function(){
                    return this.color;
                }
                return car1;
            }
    现在,若我们需要car,则只需要做如下操作就可以了:
    var car1 = CreateCar();
    var car2 = CreateCar();
    此时,我们获得的车的属性都是固定的,我们还可以动态的设定车的属性,如下:
            function CreateCar(color,doors){
                var car1 = new Object;
                car1.color=color;
                car1.doors=doors;
                car1.showColor=function(){
                    return this.color;
                }
                return car1;
            }
    现在,我们再创建车辆时,就可以动态设置car的属性了.
    但是对于上面的代码,我们发现,每当我们创建一辆车的时候,车的属性可能不同,但车的showColor方法却是一致的,而我们却每次都要创建一个相同的方法,
    我们对上面的类做以下处理:
            function showColor(){
                return this.color;
            }
        
            function CreateCar(color,doors){
                var car1 = new Object;
                car1.color=color;
                car1.doors=doors;
                car1.showColor=showColor;
                return car1;
            }
    此时,我们基本算是完成了对工厂方式的构建.
    2.构造函数方式
    创建构造函数方式和创建工厂方式一样简单,我们来看以下实例:
            function Car(color,doors){
                this.color=color;
                this.doors=doors;
                this.showColor=function(){
                    return this.color;
                }
            }
    我们注意到,在构造函数中,我们并没有创建对象,而是使用了关键字this,在使用new运算符创建新的对象时,在执行第一行代码前先创建一个对象,
    只有用this才能访问到该对象,然后直接赋予this属性,默认情况下是构造函数的返回值.
    就像工厂方式一样,构造函数方式还是会重复生成函数,尽管同样可以使用先定义函数,再引用该函数的形式,但是,这样做,在语意上并没有什么优势.
    现在,我们来看原型方式.
    3.原型方式
    该方式利用了对象prototype属性,可把它看成是创建对象所依赖的原型.在这里,是先定义一个空的构造函数来设置类名,然后将所有的属性和方法都
    定义在prototype属性上,具体见例子:
            function Car(){
            
            }
            
            Car.prototype.color='red';
            Car.prototype.doors=4;
            Car.prototype.showColor=function(){
                return this.color;
            }
    此时,我们已经定义好了一个Car类,现在,当我们使用new Car()时,原型的所有属性和方法都会被立即赋予要创建的对象,这就意味着所有的Car的实例
    都存放着指向showColor()函数的指针.
    原型方式有以下缺点:
    a.构造函数没有参数,无法在建立对象的时候就使用自定义属性.
    b.实例的所有属性都是被共享的,若其中一个改变,则可能会影响到其他的实例(此处的属性针对的是引用类型的属性).
    针对b问题,我们来看以下代码:
            function Car(){
            
            }
            
            Car.prototype.drivers = new Array("张三","李四");
        
            var car1 = new Car();
            var car2 = new Car();
            car1.drivers.push("王五");
            document.write(car2.drivers);
    注意:
    此处,我们在car1上增加了一个驾驶员,现在,我们输出的结果是car2的驾驶员.结果如何呢,让我们来看看.
    image 
    我们发现,car2的驾驶员也增加了一个,从而造成了结果并非是我们预期的结果.
    现在,我们使用混合的构造函数/原型方式来创建对象,就可以避免这个问题.
    4.构造函数/原型方式
    使用这种构造方式也很简单,主要就是:构造函数定义所有非函数的属性,原型定义所有的函数属性.结果就是所有的函数都仅仅被创建一次,而每个对象都
    拥有自己的对象属性实例.见代码:
            function Car(color,doors){
                this.color=color;
                this.doors=doors;
                this.drivers=new Array("张三","李四");
            }
            
            Car.prototype.getColor=function(){
                return this.color;
            }
    现在,我们来使用new Car操作,再为实例增加一个driver,发现增加的driver并没有影响到所有的实例,从而达到了我们想要的效果.
    5.动态原型方法
    对于习惯了使用高级编程语言的人来说,定义一个类,应该是方法和属性都在类体内,而现在属性在类体内,而方法在类体外建立,感觉似乎有些不太和谐.
    于是就出现了动态原型方法.动态原型方法和构造函数/原型方法的基本方法基本上相同,唯一的区别就是赋予对象方法的位置不同,见例子:
            function Car(color,doors){
                this.color=color;
                this.doors=doors;
                this.drivers=new Array("张三","李四");
                
                if(typeof Car._init=="undefined"){
                    Car.prototype.getColor=function(){
                        return this.color;
                    }
                    
                    Car._init=true;
                }
            }
    现在执行 new Car('red',4),在执行typeof Car._init=='undefined'之前,这个方法都一直在正常运行,直到这段代码,如果这个值未定义,
    构造函数将用原型方式定义对象方法,然后将Car._init属性定义为true,那么再此创建实例时,Car._init属性已经为true,就不会再重新对象原型方法了.
    6.混合工厂方法
    混合工厂方法和工厂方式几乎一致,它同样是先构造对象,然后再往对象中添加属性和方法,唯一的区别就是混合工厂方法在生成对象的时候依旧使用new关键字.
    见代码:
            function CreateCar(color,doors){
                var car1 = new Object;
                car1.color=color;
                car1.doors=doors;
                car1.showColor=function(){
                    return this.color;
                };
                return car1;
            }
            
            var c = new CreateCar('red',4);
    混合工厂方法和工厂方式及经典方式(构造函数,原型方式)一样都会产生问题,了解即可,不建议使用.
    以上介绍了6种构造方式,目前使用最广泛的还是构造函数/原型方式.此外,动态原型方式也很流行,在功能上和构造函数/原型方式等价.
    不过不要单独使用经典的构造函数方式或者原型方式.
  • 相关阅读:
    【HICP Gaussdb】数据库 数据库管理( 导入 导出 闪回 调优 wsr报告 ) -13
    【Flask项目】 python学习第一章
    【Flask项目】 python学习第一章
    【HICP Gaussdb】数据库 数据库管理( 备份 导入 导出 ) -12
    【系统级配置】/etc/sysctl.conf
    【Flask项目】 python学习第一章
    【HICP Gaussdb】数据库 数据库管理( 数据库安全 账户 日志管理)-11
    【Git】 python学习第一章
    【HICP Gaussdb】数据库 数据库管理(并发 锁 数据库安全)-10
    【HCIA Gauss】学习汇总-数据库管理(三范式 GAUSSDB100)-8
  • 原文地址:https://www.cnblogs.com/oneword/p/1625021.html
Copyright © 2020-2023  润新知