I have a situation as follows.
var varable_1=10;
var variable_2=20;
.....
var variable_n=10000;
function update_varable(variable){
....some code.....
}
I need to update each of those variables by calling update_variable('variable_1');update_variable('variable_2')....etc.
Is it possible?
If you want to pass the variables inside the function update_variable then you need to remove the quotes in your example. There is many ways to do it, I post a simple one. You can also pass more than one variable inside the function.
Demo here
var varable_1=10;
var variable_2=20;
var variable_n=10000;
function update_variable(x){
x = 300 //some new value
return x;
}
and the call:
variable_1 = update_variable(varable_1);
( your function name misses an "i" on some lines, it's "update_varable" )
^
missing "i"
If you have to use a string as argument for the update function, you can use eval inside of the function to get the real variable behind the string:
function update(varName) {
eval(varName + " += 1;");
}
I think array is more suitable for the task.
But you can use this code with eval function if your varaibles names are like var1, var2 .. varN:
var var1 = 10;
var var2 = 20;
function update_var(variable) {
return variable += 1;
}
function main() {
for (var i = 1; i < 3; i++) {
eval("var" + i + " = update_var(var" + i + ")");
eval("console.log(var" + i + ");");
}
}
Let's see the facts here:
Your variables have a pattern: variable_x so, for our algorithm it s just a string: 'variable_' + x
All your variables will be attached to an object, wetter it is a declared object, or a global one, for example: a, myVars, or window
Any object in javascript can be accessed using indexers, so myObject.myVar can be also written like myObject['myVar'].
Now let's see the algorithm:
function update(variable, value){
window[variable] = value;
}
You can call it like you wanted:
update('variable_1', 450.25);
function update_varable(variable){
variable += 10;
return variable;
}
Related
Suppose I need to declare a JavaScript variable based on a counter, how do I do so?
var pageNumber = 1;
var "text"+pageNumber;
The above code does not work.
In JavaScript (as i know) there are 2 ways by which you can create dynamic variables:
eval Function
window object
eval:
var pageNumber = 1;
eval("var text" + pageNumber + "=123;");
alert(text1);
window object:
var pageNumber = 1;
window["text" + pageNumber] = 123;
alert(window["text" + pageNumber]);
How would you then access said variable since you don't know its name? :) You're probably better off setting a parameter on an object, e.g.:
var obj = {};
obj['text' + pageNumber] = 1;
if you -really- want to do this:
eval('var text' + pageNumber + '=1');
I don't think you can do it sing JavaScript.I think you can use an array instead of this,
var textArray=new Array();
textArray[pageNumber]="something";
Assuming that the variable is in the global scope, you could do something like this:
var x = 1;
var x1 = "test"
console.log(window["x" + x]); //prints "test"
However, a better question might be why you want such behaviour.
You could also wrap your counter in an object:
var PageNumber = (function() {
var value = 0;
return {
getVal: function(){return value;},
incr: function(val){
value += val || 1;
this['text'+value]=true /*or some value*/;
return this;
}
};
})();
alert(PageNumber.incr().incr().text2); //=>true
alert(PageNumber['text'+PageNumber.getVal()]) /==> true
It can be done using this keyword in JS:
Eg:
var a = [1,2,3];
for(var i = 0; i < a.length; i++) {
this["var" + i] = i + 1;
}
then when you print:
var0 // 1
var1 // 2
var2 // 3
I recently needed something like this.
I have a list of variables like this:
var a = $('<div class="someHtml"></div>'),b = $('<div class="someHtml"></div>'),c = $('<div class="someHtml"></div>');
I needed to call them using another variable that held a string with the name of one of these variables like this:
var c = 'a'; // holds the name of the wanted content, but can also be 'b' or 'c'
$('someSelector').html(eval(c)) // this will just use the content of var c defined above
Just use eval to get the variable data.
I just did
I know a lot of the other answers work great, such as window["whatever"] = "x"; but I will still put my own answer here, just in case it helps.
My method is to use Object.assign:
let dict = {};
dict["test" + "x"] = "hello";
Object.assign(window, dict)
a little improvement over bungdito's answer, use the dynamic variable dynamically
var pageNumber = 1;
eval("var text" + pageNumber + "=123456;");
eval(`alert(text${pageNumber})`);
note: usage of eval is strongly discourgae
I'm using pouchDb and to query the database it requires the creation of a map function (which is standard practice for couchDB)
This version is working:
function (doc) {
if (doc.type) {
emit(doc.type)
}
}.toString()
and it results in:
"function mapFunction(doc) {
if (doc.type) {
emit(doc.type);
}
}"
However, I'm trying to change my function call to be more dynamic so I can pass a field through that the map function should be built on. With that in mind, I have a variable called field and I change my map function to this:
var field = '_id'
function (doc) {
if (doc[field]) {
emit(doc[field)
}
}.toString()
the problem is, the string that's generated is like so:
"function mapFunction(doc) {
if (doc[field]) {
emit(doc[field]);
}
}"
but I need to it to be:
"function mapFunction(doc) {
if (doc['_id']) { //or doc._id (I don't mind)
emit(doc['_id']);
}
}"
Is it possible to achieve this?
Edit: Worse case scenario, I write it as a string and do it that way but would prefer to have it as a readable function.
Perhaps a generator that takes a function, a variable name and a value and creates the string you want would do.
Something like
function functionGenerator(func, variable, value){
var r = new RegExp(variable,'gi');
return func.toString().replace(r, value);
}
function mapFunction(doc) {
if (doc[field]) {
emit(doc[field]);
}
}
var map = functionGenerator(mapFunction, 'field','\'_id\'');
console.log(map);
You could define a new method on the Function prototype that performs a toString, but allows to pass a collection of variables in an object format -- where each key is the variable to use. Those variables are injected in the string representation of the function, as var declarations right after the function body opens with a brace.
Each variable gets the JSON representation of its original value. This, of course, has some limitations, as not all values can be represented as JSON (cyclic references, objects with methods, ...etc). But it certainly works with primitive values such as strings:
Function.prototype.toStringWith = function(vars) {
return this.toString().replace(/(\)\s*{)/,
'$1\n var ' + Object.keys(vars)
.map( key => key + ' = ' + JSON.stringify(vars[key]) )
.join(',\n ') + ';');
}
// Demo
var field = '_id'
var s = function mapFunction(doc) {
if (doc[field]) {
emit(doc[field])
}
}.toStringWith({field}); // ES6 shortcut notation
console.log(s);
If you would have more variables that the function needs to "know", like size, weight, brand, then you call .toStringWith({field, size, weight, brand}), ...etc.
NB: solutions that search for the variable name in the function source and replace it with the literal value will need to be careful: the variable name could occur in a quoted string (between single quotes, doubles quotes), or template literals, or be part of a larger name, where it should not be replaced.
I think the easiest solution is a simple regexp.
var field = '_id';
var a = function (doc) {
if (doc[field]) {
emit(doc[field])
}
}.toString();
console.log(a.replace(/field/gi, field));
As I've commented, that's broad because you need to parse and re-generate this stringified function. I can't believe a plugin will force someone to stringify a function.
Since it's broad to do that replacement from field to __id (because of other identifiers, etc.) you can only re-declare this field with its initial value in the stringified function (assign its value at the top).
Not related-advice:
(Remind: var statement declares a variable in the entire scope, so the variable can be assigned before the var statement is present, too.)
//////////////////////////////////////////////
//////////////// References //////////////////
//////////////////////////////////////////////
var _stringify = JSON.stringify
//////////////////////////////////////////////
//////////////// Variables //////////////////
//////////////////////////////////////////////
var field = '__id'
/* Store the variables to be copied in the top here */
var locals = { field: field }
/* String to contain the variables */
var stringified_locals = '',
// thanks to this var length notation
// we'll separate the variables by commas
len = 0
/* Calculate the length of vars */
for (let prop in locals)
++len
/* Also useful for the variable separation */
i = 0; var i
/* Only declare the 'var' statement if there's at least
* ONE var */
if (len)
stringified_locals = 'var '
/* Now generate the string of variables */
for (let prop in locals) {
let value = _stringify(locals[prop])
stringified_locals += prop + ' = ' + value
/* Add comma separator if neccessary */
if (i++ < (len - 1))
stringified_locals += ', '
}
/* And the complete stringified function */
stringified_locals + '\r\n' +
(function (doc) {
if (doc.type) {
emit(doc.type)
}
}).toString()
Got result:
`var field = "__id"
function (doc) {
if (doc.type) {
emit(doc.type)
}
}`
You could do this:
"(function() {\n" +
"var field = " + JSON.stringify(field) + ";\n" +
"return " + mapFunction.toString() + ";" +
"})()"
Caveat: There are rare cases where JSON.stringify doesn't produce valid javascript. I don't know exactly what those cases are or whether it would be possible for a malicious user to take advantage of them in some way. (Do you trust whoever is supplying the value of field?)
Is there a way to make the value of a variable the name for another variable? For example, I want the variable name (value_of_i) to be what ever number "i" is during that iteration. The while loop below is not what I'm using it for, it's just to explain what I'm asking.
var i = 1;
while(i<10)
{
var value_of_i = "This loop has ran " + i + "times.";
i++;
}
For the first iteration, "i" is equal to 1 so I would want the variable name to be "1":
var 1 = "This loop has ran " + i + "times.";
And the second interation:
var 2 = "This loop has ran " + i + "times.";
Yes. Using bracket notation (Here is a tutorial in MDN)
Here is a working fiddle
When doing something like containingObject[stringVariable] you are accessing the property in containingObject whose name is the value stored in stringVariable.
// this assumes browser JavaScript where window is the global namespace
// in node.js this would be a little different
var i=0;
while(i<10){
window["counters"+i] = "This is loop has ran " + i + "times.";
i++;
}
console.log(counters3);
If you'd like you can use this instead of window, however this might fail in strict mode.
Here is the main explanation of how bracket notation works from the MDN link above:
Properties of JavaScript objects can also be accessed or set using a bracket notation. Objects are sometimes called associative arrays, since each property is associated with a string value that can be used to access it. So, for example, you could access the properties of the myCar object as follows:
myCar["make"] = "Ford";
myCar["model"] = "Mustang";
myCar["year"] = 1969;
You can also access properties by using a string value that is stored in a variable:
var propertyName = "make";
myCar[propertyName] = "Ford";
propertyName = "model";
myCar[propertyName] = "Mustang";
You can't make a variable name a number, its not a valid name. So var 1="" is invalid.
But to dynamically set the value you can do
var x = "variablenamehere";
window[x] = "variablevaluehere";
Thats the same as
var variablenamehere
except that it will be scoped as a global variable and will be accessible everywhere, rather than being limited to the current function scope.
Why not store your strings in an array that is indexed by i?
That way you can reference them later efficiently and easily;
var loopI = new Array();
for(var i = 0; i < 10; ++i) {
loopI[i] = "This loop has ran " + i + "times.";
}
This works:
var o = {};
var d = "dog";
for (var k = 0; k < 5; k += 1) {
o[d+k] = k*100;
}
console.log(o.dog3); // 300
This comes closer to doing what you want:
var N = {};
var M = {};
var i = 1;
while(i<10)
{
N[i] = "This loop ran " + i + " times.";
// Or, so you can use dot notation later:
M['OO'+i] = "This loop ran " + i + " times.";
// Those are capital O's, not zeros. Numbers won't work.
i++;
}
console.log(N[3]); // This loop ran 3 times.
console.log(M.OO7); // This loop ran 7 times.
The 'OO' notation could cause bewilderment and wasted time for others trying to use your code; but it could also be a source of amusement for them. This reminds me of a chess board after white's first two moves are to bring out a knight and then put it back. The board then seems to show that black moved first, and some people will endlessly insist that the configuration proves there was illegal play unless someone tells them what happened.
I have a problem to manipulate checkbox values. The ‘change’ event on checkboxes returns an object, in my case:
{"val1":"member","val2":"book","val3":"journal","val4":"new_member","val5":"cds"}
The above object needed to be transformed in order the search engine to consume it like:
{ member,book,journal,new_member,cds}
I have done that with the below code block:
var formcheckbox = this.getFormcheckbox();
formcheckbox.on('change', function(checkbox, value){
var arr=[];
for (var i in value) {
arr.push(value[i])
};
var wrd = new Array(arr);
var joinwrd = wrd.join(",");
var filter = '{' + joinwrd + '}';
//console.log(filter);
//Ext.Msg.alert('Output', '{' + joinwrd + '}');
});
The problem is that I want to the “change” event’s output (“var filter” that is producing the: { member,book,journal,new_member,cds}) to use it elsewhere. I tried to make the whole event a variable (var output = “the change event”) but it doesn’t work.
Maybe it is a silly question but I am a newbie and I need a little help.
Thank you in advance,
Tom
Just pass filter to the function that will use it. You'd have to call it from inside the change handler anyway if you wanted something to happen:
formcheckbox.on('change', function(cb, value){
//...
var filter = "{" + arr.join(",") + "}";
useFilter(filter);
});
function useFilter(filter){
// use the `filter` var here
}
You could make filter a global variable and use it where ever you need it.
// global variable for the search filter
var filter = null;
var formcheckbox = this.getFormcheckbox();
formcheckbox.on('change', function(checkbox, value){
var arr = [],
i,
max;
// the order of the keys isn't guaranteed to be the same in a for(... in ...) loop
// if the order matters (as it looks like) better get them one by one by there names
for (i = 0, max = 5; i <= max; i++) {
arr.push(value["val" + i]);
}
// save the value in a global variable
filter = "{" + arr.join(",") + "}";
console.log(filter);
});
I want to create a log function where I can insert variable names like this:
var a = '123',
b = 'abc';
log([a, b]);
And the result should look like this in the console.log
a: 123
b: abc
Get the value of the variable is no problems but how do I get the variable names? The function should be generic so I can't always assume that the scope is window.
so the argument is an array of variables? then no, there is no way to get the original variable name once it is passed that way. in the receiving end, they just look like:
["123","abc"];
and nothing more
you could provide the function the names of the variables and the scope they are in, like:
function log(arr,scope){
for(var i=0;i<arr.length;i++){
console.log(arr[i]+':'scope[arr[i]]);
}
}
however, this runs into the problem if you can give the scope also. there are a lot of issues of what this is in certain areas of code:
for nonstrict functions, this is window
for strict functions, this is undefined
for constructor functions, this is the constructed object
within an object literal, this is the immediate enclosing object
so you can't rely on passing this as a scope. unless you can provide the scope, this is another dead end.
if you pass them as an object, then you can iterate through the object and its "keys" and not the original variable names. however, this is more damage than cure in this case.
I know you want to save some keystrokes. Me too. However, I usually log the variable name and values much like others here have already suggested.
console.log({a:a, b:b});
If you really prefer the format that you already illustrated, then you can do it like this:
function log(o) {
var key;
for (key in o) {
console.log(key + ":", o[key]);
}
}
var a = '1243';
var b = 'qwre';
log({
a:a,
b:b
});
Either way, you'd need to include the variable name in your logging request if you want to see it. Like Gareth said, seeing the variable names from inside the called function is not an option.
Something like this would do what you're looking for:
function log(logDict) {
for (var item in logDict) {
console.log(item + ": " + logDict[item]);
}
}
function logSomeStuff() {
var dict = {};
dict.a = "123";
dict.b = "abc";
log(dict);
}
logSomeStuff();
Don't know if this would really work in JS... but you can use a Object, in which you can store the name and the value:
function MyLogObject(name, value) {
this.name = name;
this.value = value;
}
var log = [];
log.push(new MyLogObject('a', '123'));
log.push(new MyLogObject('b', 'abc'));
for each (var item in log) {
if (item.value != undefined)
alert(item.name + "/" + item.value);
}
Then you can loop thru this Object and you can get the name and the value
You can't access the variable names using an Array. What you could do is use objects or pass the variable names as a String:
var x = 7;
var y = 8;
function logVars(arr){
for(var i = 0; i < arr.length; i++){
alert(arr[i] + " = " + window[arr[i]]);
}
}
logVars(["x","y"]);
I had a somewhat similar problem, but for different reasons.
The best solution I could find was:
MyArray = ["zero","one","two","three","four","five"];
MyArray.name="MyArray";
So if:
x=MyArray.name;
Then:
X=="MyArray"
Like I said, it suited my needs, but not sure HOW this will work for you.
I feel silly that I even needed it, but I did.
test this.
var variableA="valor01"; <br>
var variableB="valor02";
var NamevariableA=eval('("variableA")');<br>
var NamevariableB=eval('("variableB")');<br>
console.log(NamevariableA,NamevariableB);
atte.
Manuel Retamozo Arrué