最近在做javascript开发的时候,经常会发现如下的设计模式:
var handler = {};
handler.ff = {
init:function(){
alert(11); 
 },ee:function(){
alert(22); 
 }
}
handler.ff.init.ff = handler.ff;handler.ff.init.ff.init();//结构:11
handler.ff.init.ff.init.ff.init();//结构:11
handler.ff.init.ff.init.ff.init.ff.init();//结构:11
handler.ff.init.ff.init.ff.init.ff.init.ff.init();//结构:11
handler.ff.init.ff.init.ff.init.ff.init.ff.init.ff.init();//结构:11
......
在firebug下查看handler对象,你会发现这个对象是无限递归的!
这种模式好令人困惑,特别是经过这次赋值(handler.ff.init.ff = handler.ff;),里面的init就是无限递归的,
希望大家能帮忙探讨下,谢谢!

解决方案 »

  1.   

    简化去看,其实就是地址引用。
    handler.ff.init.ff   =   handler.ff; handler.ff.init.ff就具有了handler.ff的地址,可以访问handler.ff下面的层级,于是又找到handler.ff.init.ff,而它的值还是handler.ff的地址,再找……只有在比较特殊的时候,发挥利用这个特点能有些特别的好处。
    楼主可以把你近来常见的这种应用(定义后怎么用的)发来一起讨论一下。
      

  2.   

    比较抽象的代码或写法不见得就是好的代码规范!我个人觉得这个应该不属于设计模式的范畴,严格来说只能叫做代码规范问题!init就是无限递归的,应该也不至于吧,只是它的层次比较深。
      

  3.   

    http://mat1.gtimg.com/www/hd2011/js/hd2011_noPack_v2.7.0.js(腾讯图片展示)
    http://www.nowamagic.net/jquery/jquery_AutoCompletePlugin.php里面的$.fn.autoComplete插件
    都是采用这样的模式来设计的。
    它们的模式都是这样做的
    var   handler   =   {};
    handler.prototype   =   {
    init:function(){
    alert(11);  
      },ee:function(){
    alert(22);  
      }
    }
    handler.prototype.init.prototype   =   handler.prototype; 
    javascript的原型继承用到prototype这个关键字,但是prototype是构造函数才有的属性,这里的handler明显是实例对象,因此handler是没有prototype属性的。所以我将上面的一段代码改成:
    var   handler   =   {};
    handler.ff   =   {
    init:function(){
    alert(11);  
      },ee:function(){
    alert(22);  
      }
    }
    handler.ff.init.ff   =   handler.ff; 
    结果显示能正常运行,没有报错,这就证明了这里的prototype是误导人的。
    我明白这个模式的好处就是能够很好的实现继承,但我不明白为什么可以这样写,这里的handler对象为什么是无限递归的!这里用到了javascript的什么原理呢?附图:
      

  4.   

    在服务端ORM架构中,这种循环引用非常常见,比如有两个类。一个产品类别类。一个是产品类。
    产品类别类中有产品类的集合,产品类中有产品类别的引用。这样就构成循环引用,当转化为JSON时,就会发生种循环引用问题!
      

  5.   

    有点儿明白楼主的意思了!插件很多确实这么写,很多插件内部还有类插件用法$.fn.autoComplete,比如常用的$.fn.defaults,在插件内部写成这种形式,而不是简单的一个变量,这样该插件外部,可以随时通过
    $.fn.defaults={},这样的形式,随时改变初始值!这种内部大量使用该形式的方法有很大优点,可以方便插件的改写,即使对其内部分结构不能马上看清楚,也能很方便外部改写扩展,而且不会打乱原插件!方便写插件的插件!如果换成纯JS就有点类似楼主说的这种设计模式的说法了。