JavaScript探秘:命名函数表达式替代方案

在函数内部声明一个函数
服务器君一共花费了195.038 ms进行了6次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议

其实,如果我们不想要这个描述性名字的话,我们就可以用最简单的形式来做,也就是在函数内部声明一个函数(而不是函数表达式),然后返回该函数:

  var hasClassName = (function(){

    // 定义私有变量
    var cache = { };

    // 使用函数声明
    function hasClassName(element, className) {
      var _className = '(?:^|\\s+)' + className + '(?:\\s+|$)';
      var re = cache[_className] || (cache[_className] = new RegExp(_className));
      return re.test(element.className);
    }

    // 返回函数
    return hasClassName;
  })();

显然,当存在多个分支函数定义时,这个方案就不行了。不过有种模式貌似可以实现:那就是提前使用函数声明来定义所有函数,并分别为这些函数指定不同的标识符:

  var addEvent = (function(){

    var docEl = document.documentElement;

    function addEventListener(){
      /* ... */
    }
    function attachEvent(){
      /* ... */
    }
    function addEventAsProperty(){
      /* ... */
    }

    if (typeof docEl.addEventListener != 'undefined') {
      return addEventListener;
    }
    elseif (typeof docEl.attachEvent != 'undefined') {
      return attachEvent;
    }
    return addEventAsProperty;
  })();

虽然这个方案很优雅,但也不是没有缺点。第一,由于使用不同的标识符,导致丧失了命名的一致性。且不说这样好还是坏,最起码它不够清晰。有人喜欢使用相同的名字,但也有人根本不在乎字眼上的差别。可毕竟,不同的名字会让人联想到所用的不同实现。例如,在调试器中看到attachEvent,我们就知 道addEvent是基于attachEvent的实现。当 然,基于实现来命名的方式也不一定都行得通。假如我们要提供一个API,并按照这种方式把函数命名为inner。那么API用户的很容易就会被相应实现的 细节搞得晕头转向。

要解决这个问题,当然就得想一套更合理的命名方案了。但关键是不要再额外制造麻烦。我现在能想起来的方案大概有如下几个:

  'addEvent', 'altAddEvent', 'fallbackAddEvent'
  // 或者
  'addEvent', 'addEvent2', 'addEvent3'
  // 或者
  'addEvent_addEventListener', 'addEvent_attachEvent', 'addEvent_asProperty'

另外,这种模式还存在一个小问题,即增加内存占用。提前创建N个不同名字的函数,等于有N-1的函数是用不到的。具体来讲,如果document.documentElement 中包含attachEvent,那么addEventListener 和addEventAsProperty则根本就用不着了。可是,他们都占着内存哪;而且,这些内存将永远都得不到释放,原因跟JScript臭哄哄的命名表达式相同——这两个函数都被“截留”在返回的那个函数的闭包中了。

不过,增加内存占用这个问题确实没什么大不了的。如果某个库——例如Prototype.js——采用了这种模式,无非也就是多创建一两百个函数而已。只要不是(在运行时)重复地创建这些函数,而是只(在加载时)创建一次,那么就没有什么好担心的。

延伸阅读

此文章所在专题列表如下:

  1. 我们应该如何去了解JavaScript引擎的工作原理
  2. JavaScript探秘:编写可维护的代码的重要性
  3. JavaScript探秘:谨慎使用全局变量
  4. JavaScript探秘:var预解析与副作用
  5. JavaScript探秘:for循环(for Loops)
  6. JavaScript探秘:for-in循环(for-in Loops)
  7. JavaScript探秘:Prototypes强大过头了
  8. JavaScript探秘:eval()是“魔鬼”
  9. JavaScript探秘:用parseInt()进行数值转换
  10. JavaScript探秘:基本编码规范
  11. JavaScript探秘:函数声明与函数表达式
  12. JavaScript探秘:命名函数表达式
  13. JavaScript探秘:调试器中的函数名
  14. JavaScript探秘:JScript的Bug
  15. JavaScript探秘:JScript的内存管理
  16. JavaScript探秘:SpiderMonkey的怪癖
  17. JavaScript探秘:命名函数表达式替代方案
  18. JavaScript探秘:对象Object
  19. JavaScript探秘:原型链 Prototype chain
  20. JavaScript探秘:构造函数 Constructor
  21. JavaScript探秘:可执行的上下文堆栈
  22. 执行上下文其一:变量对象与活动对象
  23. 执行上下文其二:作用域链 Scope Chains
  24. 执行上下文其三:闭包 Closures
  25. 执行上下文其四:This指针
  26. JavaScript探秘:强大的原型和原型链
  27. JavaScript函数其一:函数声明
  28. JavaScript函数其二:函数表达式
  29. JavaScript函数其三:分组中的函数表达式
  30. JavaScript函数其四:函数构造器
  31. JavaScript变量对象其一:VO的声明
  32. JavaScript变量对象其二:VO在不同的执行上下文中
  33. JavaScript变量对象其三:执行上下文的两个阶段
  34. JavaScript变量对象其四:关于变量
  35. JavaScript变量对象其五:__parent__ 属性
  36. JavaScript作用域链其一:作用域链定义
  37. JavaScript作用域链其二:函数的生命周期
  38. JavaScript作用域链其三:作用域链特征
  39. JavaScript闭包其一:闭包概论
  40. JavaScript闭包其二:闭包的实现
  41. JavaScript闭包其三:闭包的用法

本文地址:http://www.nowamagic.net/librarys/veda/detail/1639,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/1639

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

大家都在看

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《JavaScript高级程序设计(第2版)》 尼古拉斯·泽卡斯(Nicholas C.Zakas) (作者), 李松峰 (译者), 曹力 (译者)

《JavaScript高级程序设计(第2版)》在上一版基础上进行了大幅度更新和修订,融入了近几年来JavaScript应用发展的最新成果,几乎涵盖了所有需要理解的重要概念和最新的JavaScript应用成果。从颇具深度的JavaScript语言基础到作用域(链),从引用类型到面向对象编程,从极其灵活的匿名函数到闭包的内部机制,从浏览器对象模型(BOM)、文档对象模型(DOM)到基于事件的Web脚本设计,从XML(E4X)到Ajax及JSON,从高级前端开发技术到前沿的客户端存储,从最佳编程实践到即将成为现实的API,直至JavaScript未来的发展,全景式地展示了JavaScript高级程序设计的方方面面。

更多计算机宝库...