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>
Related
I have created a variable x with the keyword var but when I do the following:
var x = 10;
delete x;
It returns false. basically, I don't want to delete the x variable but my question is that why javascript does not allow to configure the variables declared in the current scope context. This is also mentioned in this documentation, but the question is why?
Because otherwise every x might or might not throw an error or might suddenly refer to another variable:
let x = 2;
{
let x = 3;
if(Math.random() > 0.5) delete x;
console.log(x); // ?!
}
That makes code conpletely error prone and unpredictable and makes it impossible to optimize, every line might suddenly become a syntax error, and thats why it is not possible to delete variables that way.
However there is another way to get this behaviour by adding an object as scope which you can mutate, and thats the reason why no one uses the with statement:
const scope = { b: 2 };
with(scope) {
console.log(b); // 2
delete scope.b;
console.log(b); // reference error
}
You cannot delete a variable if you declared it (with var x;) at the time of first use.
However, if your variable x first appeared in the script without a declaration,
you can delete the variable if you didn't use var keyword.
you can get more information from this resource
http://www.javascripter.net/faq/deleteavariable.htm
I am trying to understand the below snippet of code in javascript. I have tried to google to check the usage of creating javascript function in the below format, but i did not find any references.
Below is the my understanding of the code and plz correct if this is what the code and appreciate any reference Guide to check more on this type of using notation.
function(obj) --> this is basically running a function in the global scope which is run on the load of the page after the DOM is loaded.
obj['test'] = 'DummyObj'; This is creating a global variable. I guess i am sure on this usage.
obj['test1'] = obj['test1'] || function(){
(obj['test1'].h = obj['test1'].h||[]).push(arguments)
},
obj['test1'].m = 1 * new Date()
I am having trouble in understanding this. My analysis is this is checking for if test1 object is null it is creating a function and in that function it is checking for 'h' object and if it is null it is creating an Empty Array and pushing the local 'arguments' Object. I don't understand the second part where we have a comma and date object is created? Does it mean that it would execute as one statement and create a 'm' local variable with current Date value?
The last part where we are using (window) is what i don't understand completely. What does it mean? Can you please guide me where to further read on this
(function(obj) {
obj['test'] = 'DummyObj';
obj['test1'] = obj['test1'] || function(){
(obj['test1'].h = obj['test1'].h||[]).push(arguments)
},
obj['test1'].m = 1 * new Date();
})(window);
I took the code you posted and marked it up with some comments that try to describe what is going on.
// wrap code in a self-executing function
// this creates a scope-boundary, but since you are not using
// the "var" keyword anywhere it doesn't matter much
// the "obj" argument is the global "window" variable
// made available by the execution content (most-likely your web-browser)
(function(obj) {
// create a "test" variable that live off of the "window" object
// so: window.test = 'DummyObj';
obj['test'] = 'DummyObj';
// if window.test1 is "truthy" then this will be a no-op
// otherwise, assign window.test1 to a function
obj['test1'] = obj['test1'] || function(){
// if window.test1.h doesn't have a value,
// assign it to an empty array
// Then, add the value of window.test1.h to the
// implicit "arguments" variable that comes with each function
(obj['test1'].h = obj['test1'].h||[]).push(arguments)
}; // NOTE: I changed the comma here to a semi-colon
// set window.test1.m to the unix epoch integer value (in ms)
obj['test1'].m = 1 * new Date();
})(window);
Overall, I would say this code is cryptic and ugly. Assigning values within the same statements as a push to an array for example. Manually pushing to the arguments array is another.
I would not recommend using this code-snippit for learning JavaScript as it may teach you some anti-patterns.
This pattern (function(x) {})(y); is known as an immediately invoked function expression (IIFE) and is generally used to create a scope.
As for the rest, this is horrible garbage. Analyzing it is not terribly difficult but its really unclear why anyone would ever do any of this.
Here's the blow-by-blow:
//create a scope with the function wrapper, pass in the global
//window object under the alias 'obj'
(function(obj) {
//assign sting 'DummyObj' to the 'test' property of
//the global object, effectively creating a global variable
//and totally nullifying the reason for wrapping this in a
//function
obj['test'] = 'DummyObj';
//same thing but with the 'test1' global property/variable
//hese the logical or operator is used to conditionally
//assign the property. problem is *none* of this works,
//the following will throw:
obj['test1'] = obj['test1'] || function(){
//when called fn will attempt to conditionally assign
//an array to the h property of the test1 variable,
//ie the function itself. this is a bad idea. then it
//pushes the arguments on to that array. this is kinda
//sorta an attempt at making a function that caches its
//arguments, but it doesn't really work.
(obj['test1'].h = obj['test1'].h||[]).push(arguments)
},
//1 * new Date() will yield a millisecond timestamp, but
//+new Date() and Date.now() are both clearer. note that
//this code is also assigning a random property to the
//function object stored in test1
obj['test1'].m = 1 * new Date();
})(window);
I need to reference my object as a string but I am having issues.
ideally I would like this to work ['mystring'].myproperty; but obviously this wont work.
Is there another way besides the options below?
// auto generated ecample/////////////
var mystring = {
myproperty :'test'
}
/////////////////////////////////////
var optionA =mystring.myproperty; // works
var optionB = window['mystring'].myproperty; //gives issues
var optionC = eval('mystring').myproperty; //gives issues
var optionD = ['mystring'].myproperty; // wont work
If your variables are defined on a global scope, the following works
window[ mystring.myproperty ].data
If you are in a function's scope, things get a lot harder. Easiest way then is to define your objects in a specific namespace on window and retrieve the objects similar to the above code.
I want to determine when a particular variable is changed. I have had great success using this code to watch any property of any object that I can access, but can it be used for a variable declared like this?:
$( // line 1
function(){ // line 2
var A; // line 3
// ... lots of code that uses A as if it were a global. I wanna see what part of this code sets A ...
} // line 5999
); // line 6000
Surely A does not end up as a property of window. Is it perhaps a property of the anonymous function object which spans lines 2 thru 5999? So if I name the function so I can reference it am I able to use watch on the A var/prop somehow?
What other methods are available to me to figure out where the var gets set?
This might seem bit insane but, with a little modification, you'll be able to watch the variables pointer.
(function() {
window.ox = x = {};
x.y = 5;
})();
alert(ox.y);
This pulls it into the global territory, and should allow you to observe variable x from the global variable ox.
You can't use Object.prototype.watch on that variable, simply because it's a variable, not an object property. Regardless of its scope (which is the anonymous function you mentioned).
If you're trying to do that for debugging purposes, I believe you can watch it from your browser's developer tools.
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.