`

(Javascript)prototype的一个优势也是缺点

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

在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;

       }
之后,你可以访问一下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这样的脚本语言,由于太灵活,所以,高手写出的是天使,而新手写的,可能是魔鬼!
分享到:
评论

相关推荐

    javascript框架的优缺点

    然而,Dojo的缺点也很明显,较大的文件大小(超过200KB)可能导致首屏加载较慢,且其类库使用相对复杂,对JavaScript语法的增强不如Prototype。 二、Prototype Prototype是一个轻量级的框架,以其简洁易学的API著称...

    学习javascript面向对象 javascript实现继承的方式

    继承是面向对象编程的核心概念之一,它允许我们创建一个新对象,该对象继承现有对象的属性和方法。在JavaScript中,实现继承有多种方式,每种方式都有其特点、优势和不足。本文将详细介绍六种实现JavaScript继承的...

    长轮询Prototype+comet源代码

    Prototype是一个流行的JavaScript库,它简化了Ajax操作,为开发者提供了更方便的API。在长轮询或Comet的实现中,Prototype可以很好地处理请求的创建、发送、接收以及错误处理等环节。例如,开发者可以利用Prototype...

    js框架及介绍

    Prototype是一个基础的JavaScript库,它扩展了JavaScript的面向对象特性,并提供了DOM操作和事件处理API。Prototype是许多其他库的基础,如Scriptaculous。它简单易学,被广泛应用于Rails项目。Prototype的优点是...

    Javascript玩转继承(二)_.docx

    此外,JavaScript的每个对象只有一个原型,这意味着原型继承无法实现多继承,这与某些静态类型语言的多继承特性不兼容,也可能导致无法实现接口的概念。 总结一下,构造继承虽然可以解决多继承的问题,但存在重复...

    javascript组合使用构造函数模式和原型模式实例.docx

    它使用`function`关键字定义一个构造函数,并通过`new`关键字创建实例。构造函数通常包含了一些初始化属性和行为的方法。 **示例代码**: ```javascript function Person3(name, age, job) { this.name = name; ...

    JS框架资源

    Prototype是一个优雅的JavaScript库,它扩展了JavaScript的面向对象特性,简化DOM操作。作为其他库的基础,Prototype与Scriptaculous搭配,可以实现丰富的JS效果。Prototype因其简洁易用而被广泛应用,尤其是在Ruby ...

    js原型继承的两种方法对比介绍.docx

    这种方式相比于直接使用父类的原型,虽然会消耗更多的内存资源(因为每个子类都需要创建一个父类的实例),但它有一个明显的优势:子类对自身原型的修改不会影响到父类。 ##### 4.2 优点 - **隔离性**:子类的修改...

    js中使用使用原型(prototype)定义方法的好处详解

    在JavaScript编程中,原型(prototype)是一个非常重要的概念,它允许我们为对象定义共享的属性和方法。通过原型定义方法,可以带来一些明显的好处,主要体现在内存管理和代码组织上。 首先,原型为JavaScript中的...

    JS中自定义类和对象.doc

    这通常涉及到定义一个构造函数,并将所有方法挂载在其 `prototype` 上。 ##### 示例 ```javascript function Fruit() {} Fruit.prototype.name = "apple"; Fruit.prototype.number = 5; Fruit.prototype.showName ...

    详解JavaScript基于面向对象之创建对象(2)

    在JavaScript中,每个函数都有一个prototype属性,这个属性是一个对象,用于存放可以由该类型的所有实例共享的属性和方法。原型对象的概念允许我们不必在构造函数中定义对象信息,而是将这些信息添加到函数的...

    CoffeeScript小书1

    CoffeeScript的一个重要优势是它避免了JavaScript的一些陷阱和怪癖。例如,它处理了JavaScript中的一些隐式类型转换和函数调用问题,减少了因误用而导致的错误。同时,CoffeeScript的编译器会将源代码转换成标准的...

    Javascript 同时提交多个Web表单的方法

    例如,使用Prototype的`Ajax.Request`方法,可以为每个表单创建一个独立的请求。只需指定表单的URL和处理函数,Ajax会自动异步提交表单数据。这样,用户可以在点击修改按钮后,同时提交多个表单而不会阻塞用户界面。...

    浅谈JavaScript对象的创建方式

    为了解决这个问题,可以使用原型(prototype)来共享方法,这样所有实例都可以访问同一个方法,而无需在每个实例上创建。这将在原型链和原型模式中进一步讨论。 总结来说,JavaScript提供了多种创建对象的方式,每...

    javascript中定义类的方法汇总

    工厂方式是最简单的创建对象的方法,它通过一个工厂函数来创建对象,工厂函数可以返回一个具有特定属性和方法的新对象。如下所示: ```javascript function Car() { var ocar = new Object(); ocar.color = "blue...

    javascript中创建对象的三种常用方法

    它通过一个函数返回一个新的对象,不过这种方法并不体现对象的类型,也不利于扩展。例如: ```javascript function createObj(param) { var obj = new Object(); obj.property1 = value1; obj.method1 = ...

    实例介绍JavaScript中多种组合继承

    在JavaScript中,继承是一种机制,允许一个对象(子对象)获取另一个对象(父对象)的属性和方法。本文将详细介绍JavaScript中的几种组合继承方式,包括它们的原理、优缺点以及如何实现。 1. **组合继承**:这是...

    JavaScript中的对象继承关系

    然而,它有一个显著的缺点:无法继承父类原型上的方法和属性。这意味着如果`Desk.prototype`上有任何方法,`MJDesk`实例将无法直接访问它们,这可能导致不必要的内存消耗,因为每个子类实例都会拥有自己的一份副本。...

    初学jQuery必用书-锋利的JQuery

    - **优点:** 作为较早出现的JavaScript库之一,Prototype提供了大量的内置对象扩展,如String和Array对象的增强方法。 - **缺点:** 结构较为松散,面向对象的支持不够成熟。 - **Dojo:** - **优点:** 提供了...

Global site tag (gtag.js) - Google Analytics