zoukankan      html  css  js  c++  java
  • JavaScript类的设计

    【转载】

    Javascript与其他的面向对象语言不同,如C++,Java或PHP等。它并不是基于类的,而是基于原型的一种语言。

    1、对象创建

    在Javascript中创建一个类是非常容易的:

    var myObject = {
      aVar: 15,
      aMethod: function() {
        alert("I'm a method of the object myObject." + "aVar: " + this.aVar);
      }
    }

    你不必通过定义一个类然后实例化该类来创建一个对象。我们在这里使用了一个对象构造器。它满足了使用单个对象的场合。如果我们需要使用同一个类型的多个对象,我们必须使用一个构造器函数和new关键字。

    2、使用构造器函数

    在Javascript中没有类的概念,但是构造器是存在的。你可以编写一个函数,然后通过new关键字来创建一个对象。

    // 首先,我们为我们的类定义一个空的构造器
    function myClass() {
      this.aVar = 15;
      this.aMethod = function() {
        alert("I'm a method of the object myObject.");
      }
    }
     
    // 创建类的实例
    var A = new myClass();
     
    // 显示 15
    alert(A.aVar);
     
    // 第二个实例
    var B = new myClass();

    3、动态附加

    怎么在Javascript实现OO编程?

    恐怕最佳的方式就是充分利用prototype属性。

    关于prototype比较基本的原理的理解是:当你用prototype编写一个类后,当你new一个新的object,浏览器会自动把prototype中的内容替你附加在object上。这样,通过利用prototype,你也就实现了类似OO的Javascript。

    方法共享

    你必须使用prototype对象:

    // 我们定义了一个prototype对象的一个方法
    myClass.prototype.sharedMethod = function() { alert("I'm a shared method") }
     
    // 显示我们的信息
    A.sharedMethod();
     
    // 相同的信息
    B.sharedMethod();

    在myClass定义中并没有一个名为sharedMethod的方法。Javascript会在myClass相关联的prototype对象中寻找与该方法名相同的方法,如果存在的话,Javascript则调用该方法。

    在Javascript中,object就是个associative array。上面的例子讲到了一个function就是个类。当你编写如下function时,其实就是定义了一个类,该function就是他的构造函数。

    function MyObject(name, size){
        this.name = name;
        this.size = size;
     }

    之后,你能方便的通过MyObject类的prototype属性来方便的扩充他。

    比如,你能给他添加其他的属性和方法:

    //通过prototype属性添加tellSize 方法
    MyObject.prototype.tellSize = function()
    {
        return "size of "+this.name+" is "+this.size;
    }
    //通过prototype属性添加color 属性
    
    MyObject.prototype.color = "red";
    
    MyObject.prototype.tellColor = function()
    {
        return "color of "+this.name+" is "+this.color;
    }
    
    var myobj1 = new MyObject("tiddles", "7.5 meters");
    
    domDiv.innerHTML += myobj1.tellColor()+"<br /><br />";

    你能想象,当你调用tellColor()方法后,结果是这样的:

    color of tiddles is red

    非常方便的是,prototype属性能动态添加。比如,你需要往MyObject中加入一个height属性,并希望其提供一个tellHeight()方法来获得height属性的值。你能在上面的代码后,继续添加如下的代码:

    MyObject.prototype.height = "2.26 meters";
    
    MyObject.prototype.tellHeight = function()
    {
        return "height of "+this.name+" is "+this.height;
    }

    之后,你能访问一下myobj1的tellHeight()方法,你能得到如下的结果:

    height of tiddles is 2.26 meters

    prototype的这些动态的特性看起来有些迷人,不过我倒是反而觉得有些凉飕飕的。确实,这些特性给你非常大的灵活性,能给予你runtime改动类属性和方法的能力。不过,稍微发掘一下,会有些不良的习惯产生。

    首先,如果能动态添加属性和方法,那么非常容易让人想到,当我调用时,我想要调用的属性或方法存在不?这是个非常严肃的问题,如果当我们调用时根本没有该属性或方法,将可能导致我们的脚本down掉。

    不过也有解决办法。比如,在上面的代码中,当还没有tellHeight()方法时,我们能如下编写代码避免发生错误:

    if (myobj1.tellHeight)
    {
        domDiv.innerHTML += myobj1.tellHeight()+"<br /><br />";
    }  

    注意,一定要在if语句中,不要加方法后面的那对(),否则,直接就down掉了。有兴趣的读者能打印一下,看看分别访问myobj1.tellHeight和myobj1.tellHeight()时有什么差别。

    也许,你觉得这个是小意思。加个判断嘛,不就好了?

    对,不过下面一个问题更令人头痛。

    属性和方法在不在的问题简单,可是属性和方法变不变化的问题可就严重了。在不在我们能检测,变不变呢?比如,请看下面的代码:

    function MyObject(name, size)
    {
        this.name = name;
        this.size = size;
    }
    
    MyObject.prototype.color = "red";
    
    MyObject.prototype.tellColor = function()
    {
        return "color of "+this.name+" is "+this.color;
    }
    
    var myobj1 = new MyObject("tiddles", "7.5 meters");
    
    domDiv.innerHTML += myobj1.tellColor()+"<br /><br />";
    
    MyObject.prototype.color = "green";
    
    domDiv.innerHTML += myobj1.tellColor()+"<br /><br />";

    该代码将产生如下结果:

    color of tiddles is red
    color of tiddles is green

    请注意,你修改的是类MyObject的color属性。不过你惊奇的看到你之前实例化的对象myobj1的属性值竟然也变化了。天!如果你的项目代码是多人合作,那么,也许某个人会在编程时为了图一己之便,擅自修改你的类。于是,所有人的对象都变化了。于是,你们陷入了漫长的debug过程中。。。。。。

    上面是属性,更有方法:

    function MyObject(name, size)
    {
        this.name = name;
        this.size = size;
    }
    
    MyObject.prototype.color = "red";
    
    MyObject.prototype.tellColor = function()
    {
        return "color of "+this.name+" is "+this.color;
    }
    
    var myobj1 = new MyObject("tiddles", "7.5 meters");
    
    domDiv.innerHTML += myobj1.tellColor()+"<br /><br />";
    
    MyObject.prototype.color = "green";
    
    MyObject.prototype.tellColor = function()
    {
        return "your color of "+this.name+" is "+this.color;
    }
    
    domDiv.innerHTML += myobj1.tellColor()+"<br /><br />";

    这段代码的结果是:

    color of tiddles is red
    your color of tiddles is green

    问题来了。Javascript太灵活的编程方式多少让人不适应。如果整个Team的水平都比较高还能,没人会犯这样的错误。不过,当有个毛头小伙子不知情,擅自修改类,将导致所有的人的对象都发生变化,无论是属性还是方法。在Javascript代码变得越来越多的Ajax时代,这是个严重的问题。

    这说明,编写Javascript时,好的编程风格更加重要。记得某人原来说过这样的话,想Java和C#这些比较严格的语言,虽然降低了灵活性,但也减少了犯错误的可能。这样,即使一个新手,他写出的代码也不会和高手差太多。不过,像Javascript这样的脚本语言,由于太灵活,所以,高手写出的是天使,而新手写的,可能是魔鬼!

  • 相关阅读:
    2019-02-08 Python学习之Scrapy的简单了解
    2019-02-07 selenium...
    2019-02-06 单链表的整表创建及增删插
    2019-02-05 Linux的一些常用命令学习2
    2019-02-04 Linux的一些常用命令学习
    2019-02-03 线性表的顺序储存结构C语言实现
    2019-02-03 多进程和多线程的区别【】
    python 多进程
    Tftp文件传输服务器(基于UDP协议)
    多线程实现tcp聊天服务器
  • 原文地址:https://www.cnblogs.com/humanxiaoman/p/5022669.html
Copyright © 2011-2022 走看看