2014-09-10 64 views
0

方法虽然与我来到这个代码JavaScript对象的工作职能:请参阅主JavaScript对象从它们的子对象

var mainModule = { 
    opt : { 
     opt1: 'my option1', 
     opt2: 'my option2', 
     opt3: 'my option3', 
    }, 
    init: function(options){ 
     jQuery.extend(this.opt, options); 
     this.mainMethod(); 
    }, 
    mainMethod: function() { 
     //do Stuff 
     var color = this.opt.opt1; 
    }, 
    secondaryMethod1: function(){/*stuff*/}, 
    secondaryMethod2: function(){/*stuff*/}, 
    secondaryMethod3: function(){/*stuff*/}, 
    secondaryMethod4: function(){/*stuff*/}, 

    thirdlyMethod1: function(){/*stuff*/}, 
    thirdlyMethod2: function(){/*stuff*/}, 
    thirdlyMethod3: function(){/*stuff*/}, 
    thirdlyMethod4: function(){/*stuff*/}, 
}; 

有了这个代码,我经常检查选择的对象与this.optthis是mainModule 。 但是,所有的代码都开始凌乱地使用所有不同的方法 ,所以我以这个新代码结束了主对象中新的深度级别。

var mainModule = { 
    opt : { 
     opt1: 'my option1', 
     opt2: 'my option2', 
     opt3: 'my option3', 
    }, 
    init: function(options){ 
     jQuery.extend(this.opt, options); 
     this.mainMethod.init(); 
    }, 
    mainMethod: { 
     init: function() { 
     //do Stuff 
     var color = mainModule.opt.opt1; 
     }, 
     other: function(){}, 
     functions: function(){}, 
     here: function() {} 
    }, 
    secondary: { 
     method1: function(){/*stuff*/}, 
     method2: function(){/*stuff*/}, 
     method3: function(){/*stuff*/}, 
     method4: function(){/*stuff*/}, 
    } 
    thirdly: { 
     Method1: function(){/*stuff*/}, 
     Method2: function(){/*stuff*/}, 
     Method3: function(){/*stuff*/}, 
     Method4: function(){/*stuff*/}, 
    } 
}; 

但是用这个新我不能使用this.opt因为this不是mainModule了。

有了这种对象,是否有更好的方法来检索可选对象? 这个新的深度级别是必要的,还是应该使用一个伪命名空间?

+0

您的'opt'后面显示'=',无论如何这个JavaScript无效。 – 2014-09-10 11:09:50

+0

@EvanKnowles谢谢,编辑。 – simonLeClerc 2014-09-10 11:42:54

回答

0

您可以在IIFE中始终设置主模块,并将选项作为局部变量存储在该函数中。它看起来像这样:

var mainModule = (function() { 
    // Keep the options out of the object that's returned. 
    // Hides the options to stop things like mainModule.options.opt1 = 'EVIL'; 
    var opt = {}; 

    return { 
     init: function(options){ 
      jQuery.extend(opt, options); 
      this.mainMethod.init(); 
     }, 
     mainMethod: { 
      init: function() { 
       console.log(opt); 
      }, 
      other: function(){}, 
      functions: function(){}, 
      here: function() {} 
     }, 
     secondary: { 
      method1: function(){}, 
      method2: function(){}, 
      method3: function(){}, 
      method4: function(){}, 
     }, 
     thirdly: { 
      Method1: function(){}, 
      Method2: function(){}, 
      Method3: function(){}, 
      Method4: function(){}, 
     } 
    }; 
}()); 

现在,所有的功能都只是参考opt - 你甚至都不需要this了。

0

如果你只是想访问这些选项,那么将它们存储在@RobH建议的最高级别的闭包中将会正常工作。但是,如果你想让this在子对象中正常运行,本质上你需要将它们中的函数绑定到顶层this。蛮力的方式来做到这一点是在你的顶级init功能:

for (fn in this.secondary) { 
    this.secondary[fn] = this.secondary[fn].bind(this); 
} 

或同等学历。你可以写一个bindAll方法:

bindAll: function(section) { 
    for (fn in section) { 
     section[fn] = section[fn].bind(this); 
    } 
    return section; 
} 

然后做

this.bindAll(this.secondary); 
this.bindAll(this.thirdly); 

init程序。

这都不是理想的。基本上,JS this机制对于你想要做的那种名称间距不友好,就像我很同情。在JS中,this只存在于一个地方,只存在于一个直接位于某个对象上的函数中,而在将该对象定义为文字时,“在野外”不可用。

异常在构造函数中。你可以利用这一事实,并做

function MainModule() { 
    this.secondary = { 
     method1: function(){}.bind(this), 
     ... 
    }; 
} 
var mainModule = new MainModule(); 

然而,这种方法在这里是没有办法把secondary在原型,你可能会喜欢,它会住在每个实例。

如果是我,我可能只是扔在毛巾上,回到原来的结构/命名。