简洁优雅的JavaScript OOP风格

发布于 2022-09-14 21:44:30 字数 5139 浏览 19 评论 0

转:EtherDream

简洁优雅的JavaScript OOP风格

还是以老生常谈的User举例子,说明已在代码注释中。

  1. function User()     
  2. {     
  3.     /**   
  4.      * constant   
  5.      */   
  6.     var MAX_AGE = 100;     
  7.     var MIN_AGE = 10;     
  8.     /**   
  9.      * private variable   
  10.      */   
  11.     var m_iAge = -1;        
  12.     /**   
  13.      * constructor   
  14.      */   
  15.     function Init()     
  16.     {     
  17.         alert("User object init!");     
  18.     }     
  19.     /**   
  20.      * private method   
  21.      */   
  22.     function checkAge(age)     
  23.     {     
  24.         return MIN_AGE<=age && age<=MAX_AGE;     
  25.     }     
  26.     /**   
  27.      * public method   
  28.      */   
  29.     function setAge(age)     
  30.     {     
  31.         if(checkAge(age))     
  32.         {     
  33.             m_iAge = age;     
  34.         }     
  35.     }     
  36.     function dispAge()     
  37.     {     
  38.         alert(m_iAge);     
  39.     }     
  40.    
  41.     /**   
  42.      * Export   
  43.      */   
  44.     this.setAge = setAge;     
  45.     this.dispAge = dispAge;     
  46.      
  47.     Init();     
  48. }     
  49. var oUser = new User();     
  50.      
  51. oUser.setAge(11);     
  52. oUser.dispAge();

复制代码之所以推荐这种风格,不仅仅看起来像传统的OOP代码结构,更重要的是抛弃了this这个东西后,代码的清晰以及运行效率的提高。

显然在此模型中,是不会用到一个this来读取或设置变量的。因为无论成员变量还是函数,都是以类的闭包形式定义的,有别于以往用map[key]的方式,因此访问他们只需名字即可,而无需this,在类的内部来看每个方法都是当做private的。至于要在类的外部访问,在结尾处做一个导出指明即可。有点类似windows下导入DLL中函数,在def文件里说明下。

最后就是构造函数。之所以单独放在一个Init函数里,不单是风格上的独立性,关键是让他在类的初始化过程中最后执行,保证所有的成员级变量都已定义(成员变量可以定义在Init函数的后面)。

至于运行效率。虽然每次初始化对象的时候需要多执行接口导出函数的代码,但该模型从头到尾都没有提到prototype这个概念,所以运行时期间,访问任何一个方法都无需查找原型链表,而是最直接的键值访问。在实际应用中,对象的使用当然比创建要频繁的多。

这种设计模式更适合使用在单例模型(Singleton)当中:

  1. var objDemo = new function()  
  2. {  
  3.     //  
  4.     // 同上  
  5.     //  
  6. };

复制代码从而避免了类似这样的代码:

  1. var objDemo =  
  2. {  
  3.     _x:0,   
  4.     _y:0,  
  5.     test: function(){alert(this._x + this._y); }  
  6. };

复制代码当私有变量很多时,每次使用都要加上this.,代码会显得很累赘,最关键的是这些变量都是public的,只是他们名字前加上下划线,人为的限制在其作用域里。而用闭包变量则不然,在外部你即使想访问也是访问不到的。

细心的朋友可能发现了这个模型的缺点,就是没有了public的属性,而必须用getter和setter。确实如此,虽然大多数时候都是用getter和setter来设置访问属性,但是直接的变量访问更为灵活,有时也更有效率。所以这个模型在灵活性上多了份限制。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文