I'm trying to construct the variable name and then test if it exists using a while loop but I think I'm creating it when I test for it so keep getting 'true' and the loop goes infinite.
var1 = "value1"
var2 = "value2"
var3 = "value3"
var i = 3
Logger.log(('value'+i)==true)
var i = 4
Logger.log(('value'+i)==true)
/*
var i = 1;
while (("value"+i) != null) {
Logger.log("value"+i)
i++;
}
*/
When I build the loop I want value4 to not exist and stop the loop but it doesn't. Because I've just created it's string I suppose, so how should I be formatting the test? First question here and I have searched but the 'construction' part seems to complicate things. Thanks.
Firstly, I'll clarify a misconception,
I want value4 to not exist and stop the loop but it doesn't. Because I've just created it's string I suppose
'value'+i doesn't create a variable. It represents the string 'value3'. In JS, strings are truthy, so you logger will print true.
Now to the question, how to check if variable exists.
The cleanest way of doing this would be to use a dictionary represented by a simple js object.
let definedVariablesDictionary = {};
definedVariablesDictionary.var1 = 'value1';
let isVarialbeDefined = variable => definedVariablesDictionary[variable] !== undefined;
console.log(isVarialbeDefined('var1')); // true
console.log(isVarialbeDefined('var2')); // false
Variable names are not strings, so your attempt to construct a string that matches the name of a variable won't evaluate that string as code.
If you want to do this, you should create an object with properties that store values, like a variable would. Then you can pass a string of the property name into the object, to retrieve the value of the property.
Also, you shouldn't check to see if the value is null as null is a valid value that a variable or property could have been set to. That check wouldn't tell you explicitly if the property was defined or not, it would only tell you if the value of the property was null. Instead, checking for the existence of the property can be done by just passing the property name into the object. If it exists, then the result is "truthy" and your if statement would proceed into the true branch. If the property doesn't exist, the return value is falsy and you'd proceed into the false branch.
let myObject = {
value1:"test1",
value2:"test2",
value3:"test3"
};
for(var i = 0; i < Object.keys(myObject).length +1; i++){
// Property names can be passed as strings using bracket notation
if(myObject["value" + i]){
console.log("value" + i + " exists and has a value of: " + myObject["value" + i]);
} else {
console.log("value" + i + " is not defined");
}
}
Related
I've got a feeling this might not be possible, but I would like to determine the original variable name of a variable which has been passed to a function in javascript. I don't know how to explain it any better than that, so see if this example makes sense.
function getVariableName(unknownVariable){
return unknownVariable.originalName;
}
getVariableName(foo); //returns string "foo";
getVariableName(bar); //returns string "bar";
This is for a jquery plugin i'm working on, and i would like to be able to display the name of the variable which is passed to a "debug" function.
You're right, this is very much impossible in any sane way, since only the value gets passed into the function.
This is now somehow possible thanks to ES6:
function getVariableName(unknownVariableInAHash){
return Object.keys(unknownVariableInAHash)[0]
}
const foo = 42
const bar = 'baz'
console.log(getVariableName({foo})) //returns string "foo"
console.log(getVariableName({bar})) //returns string "bar"
The only (small) catch is that you have to wrap your unknown variable between {}, which is no big deal.
As you want debugging (show name of var and value of var),
I've been looking for it too, and just want to share my finding.
It is not by retrieving the name of the var from the var but the other way around : retrieve the value of the var from the name (as string) of the var.
It is possible to do it without eval, and with very simple code, at the condition you pass your var into the function with quotes around it, and you declare the variable globally :
foo = 'bar';
debug('foo');
function debug(Variable) {
var Value = this[Variable]; // in that occurrence, it is equivalent to
// this['foo'] which is the syntax to call the global variable foo
console.log(Variable + " is " + Value); // print "foo is bar"
}
Well, all the global variables are properties of global object (this or window), aren't they?
So when I wanted to find out the name of my variables, I made following function:
var getName = function(variable) {
for (var prop in window) {
if (variable === window[prop]) {
return prop;
}
}
}
var helloWorld = "Hello World!";
console.log(getName(helloWorld)); // "helloWorld"
Sometimes doesn't work, for example, if 2 strings are created without new operator and have the same value.
Global w/string method
Here is a technique that you can use to keep the name and the value of the variable.
// Set up a global variable called g
var g = {};
// All other variables should be defined as properties of this global object
g.foo = 'hello';
g.bar = 'world';
// Setup function
function doStuff(str) {
if (str in g) {
var name = str;
var value = g[str];
// Do stuff with the variable name and the variable value here
// For this example, simply print to console
console.log(name, value);
} else {
console.error('Oh snap! That variable does not exist!');
}
}
// Call the function
doStuff('foo'); // log: foo hello
doStuff('bar'); // log: bar world
doStuff('fakeVariable'); // error: Oh snap! That variable does not exist!
This is effectively creating a dictionary that maps variable names to their value. This probably won't work for your existing code without refactoring every variable. But using this style, you can achieve a solution for this type of problem.
ES6 object method
In ES6/ES2015, you are able to initialize an object with name and value which can almost achieve what you are trying to do.
function getVariableName(unknownVariable) {
return Object.keys(unknownVariable)[0];
}
var foo = 'hello';
var output = getVariableName({ foo }); // Note the curly brackets
console.log(output);
This works because you created a new object with key foo and value the same as the variable foo, in this case hello. Then our helper method gets the first key as a string.
Credit goes to this tweet.
Converting a set of unique variable into one JSON object for which I wrote this function
function makeJSON(){ //Pass the variable names as string parameters [not by reference]
ret={};
for(i=0; i<arguments.length; i++){
eval("ret."+arguments[i]+"="+arguments[i]);
}
return ret;
}
Example:
a=b=c=3;
console.log(makeJSON('a','b','c'));
Perhaps this is the reason for this query
I think you can use
getVariableName({foo});
Use a 2D reference array with .filter()
Note: I now feel that #Offermo's answer above is the best one to use. Leaving up my answer for reference, though I mostly wouldn't recommend using it.
Here is what I came up with independently, which requires explicit declaration of variable names and only works with unique values. (But will work if those two conditions are met.)
// Initialize some variables
let var1 = "stick"
let var2 = "goo"
let var3 = "hello"
let var4 = "asdf"
// Create a 2D array of variable names
const varNames = [
[var1, "var1"],
[var2, "var2"],
[var3, "var3"]
]
// Return either name of variable or `undefined` if no match
const getName = v => varNames.filter(name => name[0] === v).length
? varNames.filter(name => name[0] === v)[0][1]
: undefined
// Use `getName` with OP's original function
function getVariableName(unknownVariable){
return getName(unknownVariable)
}
This is my take for logging the name of an input and its value at the same time:
function logVariableAndName(unknownVariable) {
const variableName = Object.keys(unknownVariable)[0];
const value = unknownVariable[variableName];
console.log(variableName);
console.log(value);
}
Then you can use it like logVariableAndName({ someVariable })
I don't understand the purpose of this = sign on the sixth line in the code block below. I understand how the argument grabs each index number of the array, I just don't understand why chineseFood[array[0]] = array[array.length-1]; In other words, I don't get the purpose of the equal sign as if it were almost comparing each other to be stored in the empty object that is stored in the variable chineseFood. Could someone please clarify? It would be much appreciated.
function transformFirstAndLast(array) {
var chineseFood = {};
//takes 1st element (at index 0) and sets it to the last element (nth index): array(length-1)
chineseFood[array[0]] = array[array.length - 1];
return chineseFood;
}
console.log( transformFirstAndLast(['Orange', 'Lemon', 'Pork', 'Chicken']) );
Output Below
{Orange: "Chicken"}
The equals sign is not comparison, it is assignment. chineseFood is an object, which means that it can be treated like a dictionary, and its properties can be accessed using the [] operator instead of the . operator:
myObj = {
foo: "bar"
};
console.log(myObj["foo"]); // bar
console.log(myObj.foo); // bar
Likewise, you can also assign properties this way:
myObj = {};
myObj["foo"] = 3;
console.log(myObj["foo"]); // 3
console.log(myObj.foo); // 3
This is what your code is doing. It is retrieving the value of array[array.length-1], which is "Chicken". Then it is assigning this value to the property of chineseFood that has the name represented by array[0], which happens to be "Orange". Thus, the property named Orange on chineseFood is set to array[array.length - 1], which is why chineseFood evaluates to {Orange: "Chicken"}.
This method of accessing properties is especially useful when you don't know the name of the property you will be changing in advance, as is the case with this code, or when you want to create properties that have names that would otherwise be illegal:
myObj = {
".you can't usually use with spaces or start w/ periods": false
};
myObj[".you can't usually use with spaces or start w/ periods"] = true;
console.log(myObj[".you can't usually use with spaces or start w/ periods"]);
// there is no way to read this property the normal way
Basically what is does is:
your object is :
var obj = {Orange: "Chicken"};
And Your array is :
var arr = ['Orange','Lemon','Pork','Chicken']
What this line says is pick first element of the array and check for this prop in object and change its value to last element of array, here:
arr[0] = "orange";
So this line :
obj[arr[0]] can be seen as obj['orange'].
After that you change its value:
Obj[arr[0]] = arr[arr.length-1] which can be written as obj['orange'] = 'chicken'
I've got a feeling this might not be possible, but I would like to determine the original variable name of a variable which has been passed to a function in javascript. I don't know how to explain it any better than that, so see if this example makes sense.
function getVariableName(unknownVariable){
return unknownVariable.originalName;
}
getVariableName(foo); //returns string "foo";
getVariableName(bar); //returns string "bar";
This is for a jquery plugin i'm working on, and i would like to be able to display the name of the variable which is passed to a "debug" function.
You're right, this is very much impossible in any sane way, since only the value gets passed into the function.
This is now somehow possible thanks to ES6:
function getVariableName(unknownVariableInAHash){
return Object.keys(unknownVariableInAHash)[0]
}
const foo = 42
const bar = 'baz'
console.log(getVariableName({foo})) //returns string "foo"
console.log(getVariableName({bar})) //returns string "bar"
The only (small) catch is that you have to wrap your unknown variable between {}, which is no big deal.
As you want debugging (show name of var and value of var),
I've been looking for it too, and just want to share my finding.
It is not by retrieving the name of the var from the var but the other way around : retrieve the value of the var from the name (as string) of the var.
It is possible to do it without eval, and with very simple code, at the condition you pass your var into the function with quotes around it, and you declare the variable globally :
foo = 'bar';
debug('foo');
function debug(Variable) {
var Value = this[Variable]; // in that occurrence, it is equivalent to
// this['foo'] which is the syntax to call the global variable foo
console.log(Variable + " is " + Value); // print "foo is bar"
}
Well, all the global variables are properties of global object (this or window), aren't they?
So when I wanted to find out the name of my variables, I made following function:
var getName = function(variable) {
for (var prop in window) {
if (variable === window[prop]) {
return prop;
}
}
}
var helloWorld = "Hello World!";
console.log(getName(helloWorld)); // "helloWorld"
Sometimes doesn't work, for example, if 2 strings are created without new operator and have the same value.
Global w/string method
Here is a technique that you can use to keep the name and the value of the variable.
// Set up a global variable called g
var g = {};
// All other variables should be defined as properties of this global object
g.foo = 'hello';
g.bar = 'world';
// Setup function
function doStuff(str) {
if (str in g) {
var name = str;
var value = g[str];
// Do stuff with the variable name and the variable value here
// For this example, simply print to console
console.log(name, value);
} else {
console.error('Oh snap! That variable does not exist!');
}
}
// Call the function
doStuff('foo'); // log: foo hello
doStuff('bar'); // log: bar world
doStuff('fakeVariable'); // error: Oh snap! That variable does not exist!
This is effectively creating a dictionary that maps variable names to their value. This probably won't work for your existing code without refactoring every variable. But using this style, you can achieve a solution for this type of problem.
ES6 object method
In ES6/ES2015, you are able to initialize an object with name and value which can almost achieve what you are trying to do.
function getVariableName(unknownVariable) {
return Object.keys(unknownVariable)[0];
}
var foo = 'hello';
var output = getVariableName({ foo }); // Note the curly brackets
console.log(output);
This works because you created a new object with key foo and value the same as the variable foo, in this case hello. Then our helper method gets the first key as a string.
Credit goes to this tweet.
Converting a set of unique variable into one JSON object for which I wrote this function
function makeJSON(){ //Pass the variable names as string parameters [not by reference]
ret={};
for(i=0; i<arguments.length; i++){
eval("ret."+arguments[i]+"="+arguments[i]);
}
return ret;
}
Example:
a=b=c=3;
console.log(makeJSON('a','b','c'));
Perhaps this is the reason for this query
I think you can use
getVariableName({foo});
Use a 2D reference array with .filter()
Note: I now feel that #Offermo's answer above is the best one to use. Leaving up my answer for reference, though I mostly wouldn't recommend using it.
Here is what I came up with independently, which requires explicit declaration of variable names and only works with unique values. (But will work if those two conditions are met.)
// Initialize some variables
let var1 = "stick"
let var2 = "goo"
let var3 = "hello"
let var4 = "asdf"
// Create a 2D array of variable names
const varNames = [
[var1, "var1"],
[var2, "var2"],
[var3, "var3"]
]
// Return either name of variable or `undefined` if no match
const getName = v => varNames.filter(name => name[0] === v).length
? varNames.filter(name => name[0] === v)[0][1]
: undefined
// Use `getName` with OP's original function
function getVariableName(unknownVariable){
return getName(unknownVariable)
}
This is my take for logging the name of an input and its value at the same time:
function logVariableAndName(unknownVariable) {
const variableName = Object.keys(unknownVariable)[0];
const value = unknownVariable[variableName];
console.log(variableName);
console.log(value);
}
Then you can use it like logVariableAndName({ someVariable })
I have a javascript object like this
var obj={
a:{x: "someValue", y:"anotherValue"},
b:{x: "bValue", y:"anotherbValue"}
};
and I am trying to reference it like this
function(some_value){
alert("some_value is " + some_value + " with type " + typeof some_value);
// prints some_value is a with type string
var t;
t=obj[some_value]["x"]; // doesn't work
some_value="a";
t=obj[some_value]["x"]; // this does work
t=obj["a"]["x"]; // and so does this
}
I would really like understand what is going on here . Ideally I'd like to reference my
object with the value passed to the function.
Thanks
I can only assume that your variable some_value must not contain the value a. It is possible that it has extra white space characters.
In JS, when a property does not exist, it returns an undefined. in the case of the following code, if the value contained in the variable some_value does not exist as a property in obj, t is undefined
//if some_value is neither a nor b
t = obj[some_value] // t === undefined
if you try to extract a property from an undefined value, the browser reports an error:
//if some_value is neither a nor b
t = obj[some_value]["x"] // error
you can check the existence of a property before you try accessing it by using hasOwnProperty().
if(obj.hasOwnProperty(somevalue)){
//exists
} else {
//does not exist
}
you can do a "loose check" but it's not reliable as anything "falsy" will call it "non-existent" even though there is a value.
if(obj[somevalue]){
//is truthy
} else {
//obj[somevalue] either:
//does not exist
//an empty string
//a boolean false
//null
//anything "falsy"
}
I want to test whether a JavaScript variable has a value.
var splitarr = mystring.split( " " );
aparam = splitarr [0]
anotherparam = splitarr [1]
//.... etc
However the string might not have enough entries so later I want to test it.
if ( anotherparm /* contains a value */ )
How do I do this?
if (typeof anotherparm == "undefined")
An empty string evaluates to FALSE in JavaScript so you can just do:
if (anotherparam) {...}
In general it's sort of a gray area... what do you mean by "has a value"? The values null and undefined are legitimate values you can assign to a variable...
The String function split() always returns an array so use the length property of the result to figure out which indices are present. Indices out of range will have the value undefined.
But technically (outside the context of String.split()) you could do this:
js>z = ['a','b','c',undefined,null,1,2,3]
a,b,c,,,1,2,3
js>typeof z[3]
undefined
js>z[3] === undefined
true
js>z[3] === null
false
js>typeof z[4]
object
js>z[4] === undefined
false
js>z[4] === null
true
you can check the number of charactors in a string by:
var string_length = anotherparm.length;
One trick is to use the or operator to define a value if the variable does not exist. Don't use this if you're looking for boolean "true" or "false"
var splitarr = mystring.split( " " );
aparam = splitarr [0]||''
anotherparam = splitarr [1]||''
This prevents throwing an error if the variable doesn't exist and allows you to set it to a default value, or whatever you choose.
So many answers above, and you would know how to check for value of variable so I won't repeat it.
But, the logic that you are trying to write, may be better written with different approach, i.e. by rather looking at the length of the split array than assigning to a variable the array's content and then checking.
i.e. if(splitarr.length < 2) then obviously anotherparam is surely 'not containing value'.
So, instead of doing,
if(anotherparam /* contains a value */ )
{
//dostuff
}
you can do,
if(splitarr.length >= 2)
{
//dostuff
}