zoukankan      html  css  js  c++  java
  • (Javascript)prototype的一个优势也是缺点

     

    如何在Javascript实现OO编程?恐怕最好的方式就是充分利用prototype属性。关于prototype的介绍有很多,我就不赘述了。比较基本的原理是,当你用prototype编写一个类后,当你new一个新的object,浏览器会自动把prototype中的内容替你附加在object上。这样,通过利用prototype,你也就实现了类似OOJavascript

    Javascript中,object就是一个associative array。一个function就是一个类。当你编写如下function时,其实就是定义了一个类,该function就是它的构造函数。

    function MyObject(name, size)

           {

                  this.name = name;

                  this.size = size;

           }

    之后,你可以方便的通过MyObject类的prototype属性来方便的扩充它。比如,你可以给他添加其他的属性和方法。

           MyObject.prototype.tellSize = function()

           {

                  return "size of "+this.name+" is "+this.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 />";

    你可以想象,当你调用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;

           }

    之后,你可以访问一下myobj1tellHeight()方法,你可以得到如下的结果:

    height of tiddles is 2.26 meters

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

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

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

           if (myobj1.tellHeight)

           {

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

           }

    注意,一定要在if语句中,不要加方法后面的那对(),否则,直接就down掉了。有兴趣的读者可以打印一下,看看分别访问myobj1.tellHeightmyobj1.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

    请注意,你修改的是类MyObjectcolor属性。但是你惊奇的看到你之前实例化的对象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时,好的编程风格更加重要。记得某人曾经说过这样的话,想JavaC#这些比较严格的语言,虽然降低了灵活性,但也减少了犯错误的可能。这样,即使一个新手,他写出的代码也不会与高手差太多。但是,像Javascript这样的脚本语言,由于太灵活,所以,高手写出的是天使,而新手写的,可能是魔鬼!

  • 相关阅读:
    BZOJ3098 Hash Killer II 【概率】
    BZOJ4010 [HNOI2015]菜肴制作 【拓扑排序 + 贪心】
    洛谷P4364 [九省联考2018]IIIDX 【线段树】
    洛谷P4363 [九省联考2018]一双木棋chess 【状压dp】
    洛谷P2664 树上游戏 【点分治 + 差分】
    BZOJ1189 [HNOI2007]紧急疏散evacuate 【二分 + 网络流】
    BZOJ1068 [SCOI2007]压缩 【区间dp】
    BZOJ4033 [HAOI2015]树上染色 【树形dp】
    BZOJ4819 [Sdoi2017]新生舞会 【01分数规划 + 费用流】
    排序
  • 原文地址:https://www.cnblogs.com/dsliang/p/1358127.html
Copyright © 2011-2022 走看看