Use argument as variable name (Javascript) - javascript

I can't seem to find a question that answers this directly.
I'd like to use a function argument as the name of a variable within that function.
e.g.,
test(var1);
function test(foo)
{
var foo = 'Hello world!'; // Set var1
}
alert(var1); // Hello world!
Can I use the brackets here (i.e., window.[ ])?

Yeah, you can use brackets:
window[foo] = "Hello World"
Here's a JSFiddle

Er...okay, so this is almost certainly not a good idea.
Short answer: sorta. If you're running in a browser, you can do this:
var polluteGlobalNamespace = function(symbol) {
window[symbol] = "whatever";
};
polluteGlobalNamespace('foo');
console.log(foo);
But that only works for global variables. There is no way to do this with function-scoped variables, because JavaScript lacks first class environments.
But unless you're doing some deep dark metaprogramming, this isn't a good idea. It might be better to post the problem that you're trying to solve with this function to see what the idiomatic way to do it is.

Related

Should I use eval() to make variable declaration dynamic?

I need to declare some variables. If I pass the variable name to a function it should declare all variable. (variable might be using for instantiating an object.)
Short answer — you should not.
Long answer.
It is a bad way, because eval is a really dangerous thing. You can read about problems here — https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval.
Also, it can produce bad design of your application. Try to replace dynamic variable name with other solution. E.g., object property.
Let's look at the code-example:
function createObject(fieldName, value) {
return {
[fieldName]: value
}
}
In this piece of code, we don't use eval, but have object with dynamic key.
you can declare a variable dynamically without eval by using square brackets:
var variableName = 'someVariable';
someObject[variableName] = 'some value';

How to access operands or arguments in an IF/ELSE? [duplicate]

In Python one can get a dictionary of all local and global variables in the current scope with the built-in functions locals() and globals(). Is there some equivalent way of doing this in Javascript? For instance, I would like to do something like the following:
var foo = function(){ alert('foo'); };
var bar = function(){ alert('bar'); };
var s = 'foo';
locals()[s](); // alerts 'foo'
Is this at all possible, or should I just be using a local object for the lookup?
locals() - No.
globals() - Yes.
window is a reference to the global scope, like globals() in python.
globals()["foo"]
is the same as:
window["foo"]
Well, I don't think that there is something like that in js. You can always use eval instead of locals(). Like this:
eval(s+"()");
You just have to know that actually function foo exists.
Edit:
Don't use eval:) Use:
var functionName="myFunctionName";
window[functionName]();
I seem to remember Brendan Eich commented on this in a recent podcast; if i recall correctly, it's not being considered, as it adds unreasonable restrictions to optimization. He compared it to the arguments local in that, while useful for varargs, its very existence removes the ability to guess at what a function will touch just by looking at its definition.
BTW: i believe JS did have support for accessing locals through the arguments local at one time - a quick search shows this has been deprecated though.
#e-bartek, I think that window[functionName] won't work if you in some closure, and the function name is local to that closure. For example:
function foo() {
var bar = function () {
alert('hello world');
};
var s = 'bar';
window[s](); // this won't work
}
In this case, s is 'bar', but the function 'bar' only exists inside the scope of the function 'foo'. It is not defined in the window scope.
Of course, this doesn't really answer the original question, I just wanted to chime in on this response. I don't believe there is a way to do what the original question asked.
#pkaeding
Yes, you're right. window[functionName]() doesn't work in this case, but eval does. If I needed something like this, I'd create my own object to keep those functions together.
var func = {};
func.bar = ...;
var s = "bar";
func[s]();
AFAIK, no. If you just want to check the existence of a given variable, you can do it by testing for it, something like this:
if (foo) foo();

How to access variables inside function based on string variable representation

I have following function
function myFunction(){
var foo="My Foo String";
}
I would like to access my variable in a following way
function myFunction(){
var foo="My Foo String";
console.log(SOMETHINGIDONOTKNOWABOUT["foo"]);
}
I know in javascript its possible to use window["yourvariablename"] to access it, but I am interested to access function variable in similar way, therefor
Is there a way to access a javascript variable using a string that contains the name of the variable? is not a duplicate.
Eval is not correct answer for me.
Don't do this. Dynamic variables are really annoying to debug and optimize by the browser.
Use a set, a map, create a class for it, or even a simple object to store things you want to be able to access with a string.
function myFunction() {
var myData = {
"foo": "My foo string"
};
console.log( myData[ "foo" ] );
}
If I understand you question properly, you should use foo without quotes:
window[foo]
Just note that putting values on the global scope is a bad practice.
Is the following snippet the kind of things you are trying to achieve?
If you want to use a variable as an array element name, you don't have to use quotes. i.e. array["foo"] should be array[foo] if foo is a variable.
var array = [];
array['foo'] = 'bar';
// Code #1
function myFunction(element) {
console.log(array[element]);
}
myFunction('foo');
// Code #2
function myFunction() {
element = 'foo';
console.log(array[element]);
}
myFunction();
Hope it helps, in any way.

How can I target a variable with string content in a jQuery wrapper?

Basically what I am after is this,
var foo = 'I am foo!';
alert(window['foo']);
// output = I am foo!
This does not work in a jQuery wrapper, I understand that it may be due to jQuery having renamed the window object or whatnot. If anyone has any inkling as to if this may be possible in a jQuery wrapper, I would appreciate the knowledge !
foo = "I am foo!";
If you have a function scope around your var line, it'll define it as a local variable instead of a global variable. It's not jQuery "renaming the window object" or anything silly like that, it's just how var works. I'd personally doing
window.foo = "I am foo!";
// or
window["foo"] = "I am foo!";
though, to make it explicit you wanted to define a global variable. Or use a comment to say that.
jQuery doesn't rename the window object - jQuery is actually under it (window.jQuery).
Try this:
window.foo = 'I am foo!';
alert(window.foo);
For non global variables or private variables it's possible to use eval over string expressions;
var JohnDoe = function(foo){
var x;
eval("x = foo");
return x;
};
//now we can setup foo values
JohnDoe("MAKUKULA")
=> "MAKUKULA"
But it might be pointed out the following:
This feature is obsolete. Although it may still work in some browsers,
its use is discouraged since it could be removed at any time. Try to
avoid using it.

Accessing variables from other functions without using global variables

I've heard from a variety of places that global variables are inherently nasty and evil, but when doing some non-object oriented Javascript, I can't see how to avoid them. Say I have a function which generates a number using a complex algorithm using random numbers and stuff, but I need to keep using that particular number in some other function which is a callback or something and so can't be part of the same function.
If the originally generated number is a local variable, it won't be accessible from, there. If the functions were object methods, I could make the number a property but they're not and it seems somewhat overcomplicated to change the whole program structure to do this. Is a global variable really so bad?
I think your best bet here may be to define a single global-scoped variable, and dumping your variables there:
var MyApp = {}; // Globally scoped object
function foo(){
MyApp.color = 'green';
}
function bar(){
alert(MyApp.color); // Alerts 'green'
}
No one should yell at you for doing something like the above.
To make a variable calculated in function A visible in function B, you have three choices:
make it a global,
make it an object property, or
pass it as a parameter when calling B from A.
If your program is fairly small then globals are not so bad. Otherwise I would consider using the third method:
function A()
{
var rand_num = calculate_random_number();
B(rand_num);
}
function B(r)
{
use_rand_num(r);
}
Consider using namespaces:
(function() {
var local_var = 'foo';
global_var = 'bar'; // this.global_var and window.global_var also work
function local_function() {}
global_function = function() {};
})();
Both local_function and global_function have access to all local and global variables.
Edit: Another common pattern:
var ns = (function() {
// local stuff
function foo() {}
function bar() {}
function baz() {} // this one stays invisible
// stuff visible in namespace object
return {
foo : foo,
bar : bar
};
})();
The returned properties can now be accessed via the namespace object, e.g. ns.foo, while still retaining access to local definitions.
What you're looking for is technically known as currying.
function getMyCallback(randomValue)
{
return function(otherParam)
{
return randomValue * otherParam //or whatever it is you are doing.
}
}
var myCallback = getMyCallBack(getRand())
alert(myCallBack(1));
alert(myCallBack(2));
The above isn't exactly a curried function but it achieves the result of maintaining an existing value without adding variables to the global namespace or requiring some other object repository for it.
I found this to be extremely helpful in relation to the original question:
Return the value you wish to use in functionOne, then call functionOne within functionTwo, then place the result into a fresh var and reference this new var within functionTwo. This should enable you to use the var declared in functionOne, within functionTwo.
function functionOne() {
var variableThree = 3;
return variableThree;
}
function functionTwo() {
var variableOne = 1;
var var3 = functionOne();
var result = var3 - variableOne;
console.log(variableOne);
console.log(var3);
console.log('functional result: ' + result);
}
functionTwo();
If another function needs to use a variable you pass it to the function as an argument.
Also global variables are not inherently nasty and evil. As long as they are used properly there is no problem with them.
If there's a chance that you will reuse this code, then I would probably make the effort to go with an object-oriented perspective. Using the global namespace can be dangerous -- you run the risk of hard to find bugs due to variable names that get reused. Typically I start by using an object-oriented approach for anything more than a simple callback so that I don't have to do the re-write thing. Any time that you have a group of related functions in javascript, I think, it's a candidate for an object-oriented approach.
Another approach is one that I picked up from a Douglas Crockford forum post(http://bytes.com/topic/javascript/answers/512361-array-objects). Here it is...
Douglas Crockford wrote:
Jul 15 '06
"If you want to retrieve objects by id, then you should use an object, not an
array. Since functions are also objects, you could store the members in the
function itself."
function objFacility(id, name, adr, city, state, zip) {
return objFacility[id] = {
id: id,
name: name,
adr: adr,
city: city,
state: state,
zip: zip
}
}
objFacility('wlevine', 'Levine', '23 Skid Row', 'Springfield', 'Il', 10010);
"The object can be obtained with"
objFacility.wlevine
The objects properties are now accessable from within any other function.
I don't know specifics of your issue, but if the function needs the value then it can be a parameter passed through the call.
Globals are considered bad because globals state and multiple modifiers can create hard to follow code and strange errors. To many actors fiddling with something can create chaos.
You can completely control the execution of javascript functions (and pass variables between them) using custom jQuery events....I was told that this wasn't possible all over these forums, but I got something working that does exactly that (even using an ajax call).
Here's the answer (IMPORTANT: it's not the checked answer but rather the answer by me "Emile"):
How to get a variable returned across multiple functions - Javascript/jQuery

Categories