2014-09-10 63 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在原型,你可能會喜歡,它會住在每個實例。

如果是我,我可能只是扔在毛巾上,回到原來的結構/命名。