is it bad practice to parameters through a string of functions?
im building a reasonably large JS application and i wanted to get your opinions on some of the logic. i wanted to know if its considered bad practice to pass a parameter through a string of functions e.g.
function start(){
var param1 = 'me';
secondFunction(param1);
}
function secondFunction(param1){
//i dont want to user the param in this function
$.ajax('url',data,success(){
third(param1);
});
}
function third(param1){
alert(param1);
}
i guess the alternative is to use global varialbes , as below. But in my case i already have a mass of global variables and, in my eyes, some things are not important enough to the global workings of the application.
var param1;
function start(){
param1 = 'me';
secondFunction();
}
function secondFunction(){
//i dont want to user the param in this function
$.ajax('url',data,succes开发者_开发百科s(){
third();
});
}
function third(){
alert(param1);
}
So would you say passing parameters through more then one function is ok or should i be doing it another way?
Thanks
Actually, that's good practice because it avoids having any global state (i.e. ideally, the behaviour of a function would only depend on its parameters).
If you have many parameters to be passed through this way, I'd batch them together in a separate object (an 'environment' object) but apart from that it's totally fine.
Doing it this way gives you a lot of flexibility - if you want a function to operate on different data once, you'd just pass in different values, rather than changing the global state, which might affect everything else, too (Having no such global side-effects makes it very easy to parallelize functions, even though that may not be so important for JavaScript).
It is much better to pass parameters through multiple functions that to use globals.
For example, it allows you to kick off the process multiple times without messing up the global state.
Long story short, I would stick with passing the variables to avoid scope conflicts and to keep simultaneous calls functioning properly. However, I would change the format in which you pass them:
Because JavaScript is so flexible with objects, I like having a single all-encompassing parameter for functions that may need multiple parameters. This improves visibility when calling the function, makes it easy to extend the function to support additional parameters and optional parameters, and in your case makes it easy to pass parameters to additional functions in a chain. The one downside is longer function calls, but I consider the advantages well worth it. For example:
/**
* ..
*
* params.test1 Test 1 does blah
* params.test2 Test 2 does blah 2
* params.test3 Test 3 does blah 3
* params.test4 Test 4 does blah 4
*/
function test(params){
//Initialize Parameters
var test1 = params.test1;
var test2 = params.test2;
//function code
..
test2(params);
..
}
/**
* ..
*
* params.test1 Test 3 does blah 3
* params.test2 Test 4 does blah 4
*/
function test2(params){
var test3 = params.test3;
var test4 = params.test4;
//function code using test3 and test4
..
}
//Call the test function
test({test1: 'foo1', test2: 'foo2', test3: 'foo3', test4: 'foo4'});
I don't see anything wrong with either style. Method of preference here, really.
The one drawback to globals is that they stay in memory for the life of the application.
javascript have a particular way to scope variables, in the first example you define param1 in start, so all threads maded and functions that was been called in and under the context of the start functions, have the variable param1 "inherit" to call at some way. so all statements used outside of start, doesn't have the variable param1 defined. So you need to use this variable scope, only when you need to use a variable in a thread or a series of functions called.
the second example, uses a global variable scope, that means the variable is used with the global value no matter the thread you have called it, this applies only if you don't define again param1 inside another context.
so depends what are you triyng to do, in the above example, the mosst efficient is the second
This is a somewhat difficult question to answers, since it all depends on the task at hand.
The reason to pass the parameter to each function is that you may want to reuse the functions for other purposes or in a different order. In that sort of situation you definitely want to keep passing the parameter.
If the second two functions are only ever to be used by the first function, then creating a function/object that wraps things would be a good approach.
var ObjectName = {
var param = null;
function mainFunc(p) {
pararm = p;
func2();
}
function func2() {
// Use "param"
func3();
}
function func3() {
// Use "param"
}
}
// At this level of the code, the param variable is out of scope.
Too many global variable is a bad idea : You'll loose track of what-serve-what.
Too many parameters in a function is a bad idea : It will become confusing/hard to recall which parameters goes with which functions.
You could start by re-thinking your design first.
Grouping them by object, as Alexander Gessler suggested is a good idea.
Another idea is to create different scope for your function/variables... (not necessarily in an object). Functions in functions if you prefer.
Something like this would be good for you.
var cakes = function() {
// Sets a varable called param1, will use it in the prototype below
this.param1 = 'i like cakes';
// Calls the init prototype, setup below.
this.init();
};
cakes.prototype = {
init: function() {
// this.param1 is set above.
console.log(this.param1);
$.ajax({
// For example I'm just passing back the page which this javascript is in, so something returns
url: window.location.href,
// _this stores the full object, so you can get it in the callback below.
_this: this,
// success calls the ajaxCallback function, below
success: this.ajaxCallback
});
},
ajaxCallback: function() {
// this here refers to the ajax call
console.log(this);
// this._this refers to the original object, captured above.
console.log(this._this);
// this._this.param1 refers to the text set above.
console.log(this._this.param1);
}
};
// Make sure you include this or it won't work
var x = new cakes();
// or you could just do this if you are only planning on using one instance of this object on a page.
// new cakes();
Don't be afraid to use private variables, here is a quick sample on jsbin. It may not fit with what you need, but the important thing to take note of is that you're not always choosing between a global and a parameter. There are alot of choices inbetween.
var MyNamespace = function () {
// private variable
var myPrivateVariable = 'me';
// private methods
var secondFunction = function () { };
// return an object, this becomes MyNamespace
return {
// expose a method called start
start: function (arg1) {
// take the arg and assign it to a private
myPrivateVariable = arg1;
// call a private variable, we can only call / access privates from within the returned object assigned to MyNamespace
secondFunction();
},
// expose a method called third
third: function () {
// alert out our private variable
alert(myPrivateVariable);
}
};
} (); // here we're assigning the result of this function call to MyNamespace and closing around all the privates
// Usage:
MyNamespace.start('me');
MyNamespace.third();
Passing the parameter through is pefectly reasonable and actually the only feasable way if you have an asynchronous ajax call. You cannot guarantee that the global variable might be overwritten by another call to start() until the ajax calls the callback of the first start() invocation.
精彩评论