问题
While working with javascript object I came to this code :
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*/},
};
With this code I often check the opt object with this.opt
as this
is mainModule.
But all the code begin to be a littre messy with all the different method
so I ended with this new code whith a new level of depth in the main object.
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*/},
}
};
But with this new one I can't use this.opt
because this
isn't the mainModule anymore.
With this kind of object, is there a better way to retrieve the opt object ? Does this new level of depth is necessary or should I use maybe a pseudo namespace ?
回答1:
You could always set up the main module in an IIFE and store the options as a local variable in that function. Which looks like this:
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(){},
}
};
}());
Now all your functions can just reference opt
- you don't even need this
anymore.
回答2:
If you merely want to access the options, then storing them in a closure at the top level as @RobH suggests will work fine. However, if you want this
to function "correctly" in general in your subobjects, essentially you need to bind the functions in them to the top-level this
. The brute force way to do that is in your top-level init
function:
for (fn in this.secondary) {
this.secondary[fn] = this.secondary[fn].bind(this);
}
Or equivalent. You could write a bindAll
method:
bindAll: function(section) {
for (fn in section) {
section[fn] = section[fn].bind(this);
}
return section;
}
Then do
this.bindAll(this.secondary);
this.bindAll(this.thirdly);
in your init
routine.
None of this is ideal. Basically, the JS this
mechanism is not friendly to the sort of name-spacing which you are trying to do, much as I sympathize. In JS, this
exists in precisely one place and one place only which is inside a function that is directly on an object, and is not available "in the wild" while you are defining the object as a literal.
The exception is in a constructor. You could take advantage of this fact, and do
function MainModule() {
this.secondary = {
method1: function(){}.bind(this),
...
};
}
var mainModule = new MainModule();
However, with this approach here's no way to put secondary
in a prototype as you might prefer and it will live on each instance.
If it was me, I might just throw in the towel and go back to our original structure/naming.
来源:https://stackoverflow.com/questions/25763713/refer-to-the-main-javascript-object-from-functions-which-are-methods-on-a-subobj