I have a button:
<button class="btn btn-info continue">
<i class="ace-icon fa fa-check bigger-110"></i>
Continue
</button>
Onclick:
$(".continue").click(function(e) {
currForm = $(this).parents('form');
e.preventDefault();
});
I can get the id pretty easily: currForm.attr('id');, but can I set the value of this id as a variable.
Something like php's variable variables:
$a = 'hello';
$$a = 'world';
echo $hello;
Edit: I don't want to change element's id. I want to get this ID and use it as a name for a javascript variable.
For example, the element I provided above is in a form that has ID='example_id'. currForm.attr('id') will give me example_id and I want to set a variable example_id and assign a value to it.
var example_id = 'some value';
Here's 3 options for you.
eval (not recommended)
You can use the Javascript function eval to achieve what you want. But be aware, this is not recommended (I emphasized it twice, hope you understood!).
Don't use eval needlessly!
eval() is a dangerous function, which executes the code it's passed with the privileges of the caller. If you run eval() with a string that could be affected by a malicious party, you may end up running malicious code on the user's machine with the permissions of your webpage / extension. More importantly, third party code can see the scope in which eval() was invoked, which can lead to possible attacks in ways to which the similar Function is not susceptible.
It would be used like that :
eval('var ' + varName + ' = "something";');
Window object notation (Better than eval, still not really recommended)
This method consists of using the object notation provided by JavaScript on the global window object. This is polluting the global window scope and can be overridden by other JS files, which is bad. If you want to know more about that subject, this is a good question: Storing a variable in the JavaScript 'window' object is a proper way to use that object?.
To use this technic, you would do something like:
window[varName] = something;
alert(window[varName]);
Using an object (recommended)
The best solution would be to create your own variable scope. For instance, you could create on the global scope a variable and assign an object to it. You can then use the object notation to create your dynamic variables. It works the same way as the window does :
var globalScope = {};
function awesome(){
var localScope = {};
globalScope[varName] = 'something';
localScope[varName] = 'else';
notSoAwesome();
}
function notSoAwesome(){
alert(globalScope[varName]); // 'something';
alert(localScope[varName]); // undefined
}
You can do it using javascript object:
var currForm = $(this).parents('form');//form id="hello"
var obj = {};
obj[currForm.attr('id')] = 30;
console.log(obj.hello)
You can use and object to store your variables in:
var variables = {};
to add a variable just type:
variables[name] = value;
and to access the value:
variables[name]
Check it out here: jsFiddle
Button 2 reads the value of variables[formid] and button 1 sets formid to submitted
Try one of the following:
$(this).attr(example_id, "value")
Or
window[ currForm.attr(id)] = 12;
Or
window[ this.id ] = 12;
Your best option for archieving what you really want is using eval(), like this:
eval("var " + currForm.attr('id');
Check this link ->
Dynamic Variables in Javascript
Use eval (but not recommended):
var id = 'that_id';
eval(id+" = 'other id';");
alert(that_id); // results: 'other id'
Related
I want some jquery variables to be created dynamically. In my code I am having a loop, and with the loop values I want to create some variables. Here is my sample code.
array=["student","parent","employee"]
$.each(user_types, function( index, value ){
var value+"_type" // this is the type of variable i want to build.
})
I have found about eval function. That code goes like this.
var type = "type"
eval("var pre_"+type+"= 'The value of dynamic variable, val';");
alert(pre_type) // this gives 'The value of dynamic variable, val' in alert box.
Is there any alternate ways as I have read the eval function is not prefered while coding .js files.
Any time you find yourself using a variable in the name of a variable, you probably want to use an object literal. Create the object with curly braces {}, and then set the object property key using square bracket notation:
var user_types = ["student","parent","employee"];
var types = {};
$.each(user_types, function( index, value ){
types[value] = 'The value of dynamic variable, val';
});
JSFiddle
Note: You haven't tagged it, but I assume because you've used each() that you are using jQuery, please correct me if I'm wrong.
First of all i must say that i can't think of any reason why you want to do this.
If you really need to have those variables, in global scope, you can do the following:
var array=["student","parent","employee"]
array.forEach(function(value){
window[value+"_type"] = 'My value ' + value;
});
console.log(student_type);
console.log(parent_type);
console.log(employee_type);
If you don't want the variables in global scope, i'm afraid i don't know an elegant solution.
I used array.forEach instead of your jQuery loop because the problem is not related to jQuery at all and because i don't think you said enough of your logic to make a coherent example.
EDIT: I should make it clear that while the 'variables' created behave mostly like other variables in global scope, they are NOT variables. Here is how they differ:
// Difference 1: hoisting
console.log(x); // undefined
console.log(y); // ReferenceError: y is not defined
var x = 5;
window[y] = 5;
console.log(x); // 5
console.log(y); // 5
// Difference 2: [[Configurable]]
delete x;
delete y;
console.log(x); // 5
console.log(y); // ReferenceError: y is not defined
If you want to add an intermediate variable inside the string, you can do it as follows:
var itemSelect: number = 1;
$(`#tab${this.itemSelect}-tab`).tab('show');
/* Result -> $(`#tab1-tab`).tab('show'); */
/* HTML */
<a id="tb1-tab"> </a>
I have a global variable which looks like this:
var socket_x = 'whatever';
The thing is that "x" would depend on the user session. Let's say the user id is 123, i want the global variable to be:
var socket_123 = 'whatever';
This way, each user browsing will have his own socket set as global variable.
I just don't know how to do this.
I know I can use:
eval('socket_' + userId) = 'whatever'; //not recommended
window['socket_' + userId] = 'whatever'; //best
but if I want to declare the global variable like this, it won't work:
var eval('socket_' + userId) = 'whatever';
Can someone help me on this one?
Thank you.
PS: I know "eval" should not be used for this but it's just for the illustration sake.
EDIT:
Thank you for your answer, all of you, but it just doesn't work.
This is what I have so far for my global variable (it works as it is but I don't want to mix php with javascript):
var socket_<?php echo $_SESSION['user_id'];?> = io.connect( 'http://pubsub.pubnub.com', pubnub_setup_private );
if I do this instead, like you suggest:
window['socket_'+actual_user_id]= io.connect( 'http://pubsub.pubnub.com', pubnub_setup_private );
it just won't work.
if I do this as a local variable, it works:
eval('socket_'+actual_user_id).emit( 'all', msg_all );
But if I do that, it doesn't:
window['socket_'+actual_user_id].emit( 'all', msg_all );
So I got 2 problems here:
window never works for me, eval does.
eval works as a local variable but not as a global one. It seems that "var" is needed but using "var" just before eval is not accepted.
I'm ok with avoiding eval but I just don't know how.
PS: I'm on a global context here.
window['socket_'+userId] = "whatever";
That should work just fine. Do NOT use eval for something as trivial as this.
Although, even better would be an array:
socket[userId] = "whatever";
A variable attached to window is a global variable. For example:
var myVar = 'hello';
alert( window.myVar );
... will alert 'hello' (assuming this code is run in the global context, of course).
EDIT: I would try ensuring your variable is being attached to the window object by specifying it manually with window[xxx] = yyy instead of var xxx = yyy. This means it will always work even if it's in a function call. Try playing with this fiddle and see if you can break it the same way as your real code: http://jsfiddle.net/2hYfa/
In PHP we can do this:
$variable = "name_of_variable";
$this->{$variable} = "somevalue";
how to do this in javascript?
where use case should look like:
function Apple(){
var name = "variable_name";
this.(name) = "value";
}
console.log(new Apple());
to output
[Apple: {variable_name:"value"}]
try:
this[name] = "value";
All objects can use dot and array notation for variable access.
Also note, this will allow you to create name value pairs that are inaccessible via dot notation:
var foo = {};
foo['bar-baz'] = 'fizzbuzz';
alert(foo.bar-baz); //this will not work because `-` is subtraction
alert(foo['bar-baz']); //this will work fine
If you are creating a new object literal, you can use string literals for the names for values with special characters:
var foo = {'bar-baz':'fizzbuzz'};
But you will not be able to use variables as the key within an object literal because they are interpreted as the name to use:
var foo = 'fizz';
var bar = { foo:'buzz' }
alert( bar.fizz ); //this will not work because `foo` was the key provided
alert( bar.foo ); //alerts 'buzz'
Because other answerers are mentioning eval, I will explain a case where eval could be useful.
Warning! Code using eval is evil, proceed with caution.
If you need to use a variable with a dynamic name, and that variable does not exist on another object.
It's important to know that calling var foo in the global context attaches the new variable to the global object (typically window). In a closure, however, the variable created by var foo exists only within the context of the closure, and is not attached to any particular object.
If you need a dynamic variable name within a closure it is better to use a container object:
var container = {};
container[foo] = 'bar';
So with that all being said, if a dynamic variable name is required and a container object is not able to be used, eval can be used to create/access/modify a dynamic variable name.
var evalString = ['var', variableName, '=', String.quote(variableValue), ';'].join(' ')
eval( evalString );
You can use square bracket notation in Javascript:
variable = "name_of_variable";
window[variable] = "somevalue";
You can do this with any object in Javascript.
var name = "var_name";
var obj = {};
obj[name] = 'value';
alert(obj.var_name);
I suggest using associative arrays to do whatever you're trying to do as they are significantly cleaner and easier to debug.
However if you really insist, you can use eval() to accomplish this:
variable = "name_of_variable";
eval(variable + " = \"somevalue\""); // this will work, but please do not do it
alert(name_of_variable);
EDIT: It his just come to my attention that a significantly easier (and better) way of doing this is by simply accessing the window object:
window[variable] = "somevalue";
http://jsfiddle.net/WJCrB/
window['name_of_variable'] = 'somevalue';
or
eval('var ' + variable_name + ' = ' + variable_name + ';');
Beyond that, don't do this. Variable variables are NEVER a good idea and make it nearly impossible to debug problems when (invariably) things break.
I am now in the process of removing most globals from my code by enclosing everything in a function, turning the globals into "pseudo globals," that are all accessible from anywhere inside that function block.
(function(){
var g = 1;
var func f1 = function () { alert (g); }
var func f2= function () { f1(); }
})();
(technically this is only for my "release version", where I append all my files together into a single file and surround them with the above....my dev version still has typically one global per js file)
This all works great except for one thing...there is one important place where I need to access some of these "globals" by string name. Previously, I could have done this:
var name = "g";
alert (window[name]);
and it did the same as
alert(g);
Now -- from inside the block -- I would like to do the same, on my pseudo-globals. But I can't, since they are no longer members of any parent object ("window"), even though are in scope.
Any way to access them by string?
Thanks...
Basically no, as answered indirectly by this question: Javascript equivalent of Python's locals()?
Your only real option would be to use eval, which is usually not a good or even safe idea, as described in this question: Why is using the JavaScript eval function a bad idea?
If the string name of those variables really and truly is defined in a safe way (e.g. not through user-input or anything), then I would recommend just using eval. Just be sure to think really long and hard about this and whether there is not perhaps a better way to do this.
You can name the function you are using to wrap the entire code.
Then set the "global" variable as a member of that function (remember functions are objects in JavaScript).
Then, you can access the variable exactly as you did before....just use the name of the function instead of "window".
It would look something like this:
var myApp = new (function myApp(){
this.g = "world";
//in the same scope
alert ( "Hello " + this["g"]);
})();
//outside
alert ( "Hello " + myApp["g"]);
if you want to access something in a global scope, you have to put something out there. in your case it's probably an object which references your closed off function.
var obj1 = new (function(){
var g = 1;
var func f1 = function () { alert (g); }
var func f2= function () { f1(); }
})();
you can add a method or property as a getter for g. if the value of g isn't constant you might do like
this.getG = function() { return g; };
you can work from there to access items by name, like
alert( obj1["getG"]() );
alert( window["obj1"]["getG"]() );
Basically this is a question how to access local scope handler. I trying to achieve something similar for global variable definition like:
window['newObject'] = "some string";
alert(newObject);
but for local scope. Right now only solution I have is using evals:
eval("var newObject='some string'");
But this is really ugly solution... The best one would be like using some reference to local scope like in a window[] solution, but I never heard of any reference to local scope... Any ideas ?
Example goes here:
function x(arg)
{
localScope[arg.name]=arg.value;
alert(sex);
}
x({name:"sex", value:"Male"});
What you're looking for is called the call object. But according to this, you can't access it directly, so you're out of luck.
Why not create an object in local scope and then use it as a container for any variables you wish to create dynamically?
function x(arg)
{
var localSpace = {};
localSpace[arg.name] = arg.value;
}
Okey I found related question that is talking about what I need...
How can I access local scope dynamically in javascript?
I just remember that in ECMA 262 is only one way to add dynamically local variables to scope using "with" statement (and eval of course), here are solution:
var x=function(obj)
{
with(obj)
{
alert(someObj);
}
}
alert(typeof someObj);
x ( {someObj:"yea"}) ;
alert(typeof someObj);
I must be missing something. How is what you want different from just doing:
var newObject = 'some string';
? (OP has clarified question)
I don't think there is a way to do what you are asking. Use members of a local object, e.g.
function doSomething(name, value)
{
var X = {};
X[name] = value;
if (X.foo == 26)
alert("you apparently just called doSomething('foo',26)");
}
If you choose a 1-character variable like $ or X, it "costs" you 2 characters (variable name plus a dot), and avoids trying to use eval or doing something weird.
You could try the named arguments trick
EDIT: This isn't cross browser
function x( {sex:sex, height:height} ) {
alert( sex );
alert( height );
}
x( { sex: 'male', height: 'short' } );
x( { height: 'medium', sex: 'female' } );
// male
// short
// female
// medium
Not sure what you need exactly, but here's my 2 cents.
The only way to dynamically create vars in an existing function is the eval method you've already mentioned.
Another option (mentioned by others) is that your function take a context map, and the template access it with dot notation (context.var1)
My final suggestion is the Function constructor. But I have a feeling this may be what you're looking for. (Note that the function constructor suffers from the same problems as an eval call)
var arg1 = "first";
var arg2 = "last";
// This is the body of the function that you want to execute with first
// and last as local variables. It would come from your template
var functionBody = "alert(first + ' ' + last)";
var myCustomFun = new Function(arg1, arg2, functionBody);
myCustomFun("Mark", "Brown"); // brings up and alert saying "Mark Brown";
Hope it helps
Interesting question, never thought of something like this. But what is the usecase?
The reason you'd want to do something like this, is if you don't know the name of the variable. But then in that case, the only way to access the variable again would be using the same reference object. I.e. you could just use any old object to store data in.
Reading from such a reference object would be interesting for debugging purposes, but I don't see why you'd want to write to it.
Edit:
The example you posted doesn't convince me of the need for access to the local scope, since you still have the name sex hard coded in the alert. This could be implemented as:
function x(arg)
{
container = {};
container[arg.name] = arg.value;
alert(container.sex);
}
Could you elaborate more on the example?
I'm not entirely sure I understand your question. When creating a class x, I generally do this:
function x(args) {
var _self = this;
_self.PriviledgedMethod(a) {
// some code
}
function privateMethod(a) {
// some code
}
}
var newObject = new x(args);
You can continue to access _self and args since it is closed on by the contained functions.