Reputation: 155
I have a function that is rather complex. It takes several arguments, one of them being an object from an API. It extracts information from that object, performs some checks and stores the results in variables, then does multiple operations with those variables and the arguments.
In order to make this more manageable I split those multiple operations into smaller functions and moved them out of the main one. The problem is that I need to pass all variables and arguments from the main function to the others in order for them to work.
I know I could just put them in an object and pass that object to the subfunctions, but I was wondering if there's a way to do something like this:
function main(obj, arg2, arg3, arg4) {
/* Multiple checks with values of obj */
var myVar1 = result1;
var myVar2 = result2;
/* More variables here */
subFunction1();
subFunction2();
subFunction3();
}
function subFunction1() {
/* Has access to all variables and arguments from main() */
}
function subFunction2() {
/* Has access to all variables and arguments from main() */
}
function subFunction3() {
/* Has access to all variables and arguments from main() */
}
I'm reluctant to use an object mainly because I'd need to make each of the subfunctions extract the information from it and re-define the variables locally.
I need this for an ES3 environment, but I'm open to hear about features from later specifications in case they're handy for future situations.
Upvotes: 0
Views: 481
Reputation: 557
I agree with Pavlo's answer and I'd recommend you to pass the necessary arguments to your functions, keeping good coding practice. But if you don't mind using dirty solutions, here's a hack:
function main() {
var myVar1 = 1;
var myVar2 = 2;
var myVar3 = 3;
eval(function1.toString() + function2.toString() + function3.toString());
function1();
function2();
function3();
}
function function1() {
console.log(myVar1);
}
function function2() {
console.log(myVar2);
}
function function3() {
console.log(myVar3);
}
main();
You could also make use of call() or apply() (Which are compatible with ES3) to change your declared function's context to whatever context you want them to have:
function main() {
this.myVar1 = 1;
this.myVar2 = 2;
this.myVar3 = 3;
function1.call(this);
function2.call(this);
function3.call(this);
}
function function1() {
console.log(this.myVar1);
}
function function2() {
console.log(this.myVar2);
}
function function3() {
console.log(this.myVar3);
}
main();
But, in this specific case, you wouldn't need to use call()
at all, as you can see here:
function main() {
this.myVar1 = 1;
this.myVar2 = 2;
this.myVar3 = 3;
function1();
function2();
function3();
}
function function1() {
console.log(this.myVar1);
}
function function2() {
console.log(this.myVar2);
}
function function3() {
console.log(this.myVar3);
}
main();
You can see how the keyword this
works by clicking here.
Upvotes: 0
Reputation: 1197
What you are asking for is considered bad coding practice, passing the arguments to the functions
would be a better solution, because now you need to store some global variables (I have very limited knowledge of what is possible in ES3), but here is how you could solve it.
var APIobj = undefined;
var argument2 = undefined;
var argument3 = undefined;
var argument4 = undefined;
function main(obj, arg2, arg3, arg4) {
APIobj = obj;
argument2 = arg2;
argument3 = arg3;
argument4 = arg4;
subFunction1();
subFunction2();
subFunction3();
}
function subFunction1() {
/* Has access to APIobj, argument2, argument3 and argument4 */
}
function subFunction2() {
/* Has access to APIobj, argument2, argument3 and argument4 */
}
function subFunction2() {
/* Has access to APIobj, argument2, argument3 and argument4 */
}
I get the feeling that you do not want to put the function within main
because its bloating the main
function too much, so you would rather have it separated and then call the separated functions within main.
Upvotes: 1
Reputation: 3873
If you really need all the variables from the parent function, the easiest way would be to define the sub functions at the bottom of the main function, so they have the same scope. Will not work if you want to re-use subFunctions somewhere else.
It's more coupled that the example that you give, but in case they all need to use same variables that makes sense.
function main(obj, arg2, arg3, arg4) {
/* Multiple operations with values of obj */
var myVar1 = result1;
var myVar2 = result2;
/* More variables here */
subFunction1();
subFunction2();
subFunction3();
function subFunction1() {
/* Has access to all variables and arguments from main() */
}
function subFunction2() {
/* Has access to all variables and arguments from main() */
}
function subFunction2() {
/* Has access to all variables and arguments from main() */
}
}
Optionally, you can do some kind of initialisation, like this:
function init(obj, arg2, arg3, arg4) {
/* Multiple operations with values of obj */
var myVar1 = result1;
var myVar2 = result2;
/* More variables here */
function subFunction1() {
/* Has access to all variables and arguments from main() */
}
function subFunction2() {
/* Has access to all variables and arguments from main() */
}
function subFunction3() {
/* Has access to all variables and arguments from main() */
}
return {
subFunction1,
subFunction2,
subFunction3
}
}
var service = init(obj, arg2, arg3, arg4);
service.subFunction1();
service.subFunction2();
service.subFunction3();
In that case the functions will also share the same scope.
Upvotes: 1
Reputation: 5639
even if this is not exactly what you are searching for maybe this helps you:
var main = {
/* Multiple operations with values of obj */
myVar1: "hallo",
myVar2: "welt",
/* More variables here */
x: subFunction1
}
function subFunction1() {
/* Has access to all variables and arguments from main() */
console.log(this.myVar1)
}
main.x()
https://jsfiddle.net/7x275ruz/
Upvotes: 1
Reputation: 724
You can make use either define the subfunctions inside the main one, like:
function main(){
// ...
function subfunction(){}
function subfunction2(){}
// ...
}
or you define it on the prototype of main(), where main would be a constructor.
function main() {
// variables and codes...
}
main.prototype.subfunction1 = function() {}
main.prototype.subfunction2 = function() {}
In the second case though, you would have to access the variables using the this
context, like this.var1
and main called using new main()
Upvotes: 0
Reputation: 15851
Simply move functions in appropriate context, this is perfectly legitimate in Javascript:
function main(obj, arg2, arg3, arg4) {
/* Multiple operations with values of obj */
var myVar1 = result1;
var myVar2 = result2;
/* More variables here */
function subFunction1() {
/* Has access to all variables and arguments from main() */
}
function subFunction2() {
/* Has access to all variables and arguments from main() */
}
function subFunction2() {
/* Has access to all variables and arguments from main() */
}
subFunction1();
subFunction2();
subFunction3();
}
Upvotes: 1