I'm currently running a series of functions where the first argument is a variable defined elsewhere, and the second argument is a string that happens to be identical to the variable name:
assignString(Hello, 'Hello')
assignString(World, 'World')
assignString(Foo, 'Foo')
assignString(Bar, 'Bar')
...
Ideally I would like to simplify this to something like this:
['Hello', 'World', 'Foo', 'Bar'].forEach(() => { assignString... })
or
[Hello, World, Foo, Bar].forEach(() => { assignString... })
Is this actually possible?
const vars = { Hello, World, Foo, Bar };
Object.keys(vars).forEach(key => assignString(vars[key], key));
I think the only way you could dynamically create variables based on a string value is by doing something like this:
var exampleStringValue = 'HELLO';
window[exampleStringValue] = exampleStringValue;
console.log(window.HELLO);
// or, since window is the global context in the browser
console.log(HELLO)
I honestly can't say I can dream up a use-case where that's a good practice, but I don't know your use-case, so no judgement here :)
I'd also like to point out this little library that I've found useful for creating objects where the keys have same value as the name of the key: https://github.com/STRML/keyMirror. I've found that to be used pretty heavily in the React community.
Since the variable name and the string are equivalent, there's no need to pass it in twice. I'd rather pass in the scope of the variable. You could do this so it works in whatever scope you're in:
function assignString(scope, val){
scope[val] = val;
}
Called like
assignString(window, "Hello");
Output of console.log(Hello) ==> "Hello"
Using the new ES6 Map object, we can create name/value pairs in a structure that can then be turned into an Array, so forEach can work:
// Variables that assignString will need:
var Hello = "var1", World = "var2", Foo = "var3", Bar = "var4";
// Map object that contains name of variables and strings that match variable name
var m = new Map([[Hello, "Hello"],[World,"World"],[Foo, "Foo"], [Bar, "Bar"]]);
// Turn Map into Array so forEach will work:
var a = Array.from(m);
// Call forEach which calls assingString and passes key name
// (variable name) and string value
a.forEach((value) => { assignString(value[0], value[1]); });
See this fiddle: https://jsfiddle.net/qnwsajes/34/
You can create an object with your data, iterate over the keys, and pass the key-value-pair to your assignString function.
var data = {
Hello: Hello,
World: World,
Foo: Foo,
Bar: Bar
}
Object.keys(data).forEach(key => assignString(data[key], key));
Related
I'm running a node software where in a certain context of the software there is an object which one of it's keys is a Symbol, and it's value is an object. For example:
object = {Symbol(symbol_name): another_object}
I'm trying to get to the 'another_object' keys and values and can't find the way to do so. Suggestions anyone?
The best approach would be to save the Symbol in a variable first, then just use bracket notation to look it up:
const sym = Symbol('symbol_name');
const object = {[sym]: { foo: 'bar' }}
console.log(object[sym]);
If you don't have a reference to the symbol, and the object contains only one symbol, you can get it with getOwnPropertySymbols:
const object = {
[Symbol('symbol_name')]: {
foo: 'bar'
}
};
const sym = Object.getOwnPropertySymbols(object)[0];
console.log(object[sym]);
Put the object key in brackets like this:
object = {[Symbol(symbol_name)]: another_object}
Say I have an array of functions:
let myArray = [foo, bar, baz];
and i want to convert that to an array of strings with the function names:
let myArrayAsStrings = ['foo', 'bar', 'baz'];
How can I do that?
I have tried doing
myArray.map(fn => fn.name)
however my babel config is i think mangling the function names, so it cannot be guaranteed that the name will be the same.
Wondering if there's some kind of 'convert var name to string' method I don't know about?
It’s unclear if foo, bar, and baz are normal functions (function foo() {}), unnamed functions (var foo = funtion () {}), or arrow functions (which can be only anonymous). fn.name will work only for the first case, the other two won’t have a name.
Theoretically, this could be a workaround:
var myArrayAsStrings = Object.keys({ foo, bar, baz });
This will first store each function as a property and then we can extract properties names from the object as an array of keys. The downside of this solution is that the order either cannot be guaranteed.
However, if there is some sort of uglification then the original names from the code will be lost.
Seems to be working fine, just add toString() at the end and push it into an array
var foo = function() {
console.log("Foo");
};
var bar = function() {
console.log("bar");
};
var baz = function() {
console.log("baz");
};
let myArray = [foo, bar, baz];
let myArrayAsStrings = [];
myArray.map(fn => myArrayAsStrings.push(fn.name.toString()));
console.log(myArrayAsStrings);
EDIT: This answer is assuming there's an array of vars (as the title says), not an array of functions:
A one line solutuion :
myArray.toString().split(",")
Im trying to use a command for a chat program and i want to edit a variable with a command like !editvar variablehere value
so if it variablehere = '123' i want to turn '123' into just 123 or something like 'hello' into hello, in simple words im trying to make a string from a chat message into a variable name
ive tried parsing and string.raw and none worked
if(message.startsWith('keyeditvar')) {
console.log(message)
var bananasplit = message.split(' ');
var bananasplitted = json.parse(bananasplit)
console.log(bananasplitted[0].keyeditvar)
var variable = bananasplit[1]
console.log(variable)
var value = bananasplit[2]
console.log(value)
var variable2 = String.raw(variable)
console.log(variable2)
var value2 = String.raw(value)
console.log(value2)
}
i expected it to work ig
im trying to turn a string into a variable name
In Javascript, you don't usually dynamically define new variables with custom names in the current scope. While you can do it at the global scope, you cannot easily do it in the function or block scope without using tools that are generally not recommended (like eval()).
Instead, you use an object and you create properties on that object. You can use either a regular object and regular properties or you can use a Map object with some additional features.
For a regular object, you can do thing like this:
// define base object
let base = {};
// define two variables that contain variable name and value
let someName = "greeting";
let someValue = "hello";
// store those as a property on our base object
base[someName] = someValue;
console.log(base); // {greeting: "hello"}
Then, you can change the value:
someValue = "goodbye";
base[someName] = someValue;
console.log(base); // {greeting: "goodbye"}
Or, you can add another one:
let someOtherName = "salutation";
let someOtherValue = "Dear Mr. Green";
base[someOtherName] = someOtherValue;
console.log(base); // {greeting: "goodbye", salutation: "Dear Mr. Green"}
console.log(base.greeting) // "goodbye"
console.log(base[someName]); // "goodbye"
console.log(base.salutation) // "Dear Mr. Green"
console.log(Object.keys(base)) // ["greeting", "salutation"]
You can think of the Javascript object as a set of key/value pairs. The "key" is the property name and the value is the value. You can get an array of the keys with:
Object.keys(obj)
You set a key/value pair with:
obj[key] = value;
You get the value for a key with:
console.log(obj[key]);
You remove a key/value pair with:
delete obj[key]
With a plain Javascript object like this, the keys must all be strings (or easily converted to a string).
If you have non-string keys, you can use a Map object as it will take any object or primitive value as a key, but it uses get() and set() methods to set and get key/values rather than the assignment scheme of a plain object.
Please, next time put a clean code...
To convert a string to a number. You can use the function : Number(object)
So for example :
Number('123')
will return 123.
If the object value is not a correct number, it will return NaN.
So for example :
Number('hello')
will return NaN.
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'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 })