How do I reference an object dynamically? - javascript

In Javascript, I have an object:
obj = { one: "foo", two: "bar" };
Now, I want do do this
var a = 'two';
if(confirm('Do you want One'))
{
a = 'one';
}
alert(obj.a);
But of course it doesn't work. What would be the correct way of referencing this object dynamically?

short answer: obj[a]
long answer: obj.field is just a shorthand for obj["field"], for the special case where the key is a constant string without spaces, dots, or other nasty things. in your question, the key wasn't a constant, so simply use the full syntax.

Like this:
obj[a]

As a side note, global variables are attached to the "window" object, so you can do
var myGlobal = 'hello';
var a = 'myGlobal';
alert(window[a] + ', ' + window.myGlobal + ', ' + myGlobal);
This will alert "hello, hello, hello"

Related

Execute function off of variable

I am quite newish at nodejs and javascript in general, and I have been trying to figure out how to make a function that executes on a variable, e.g.
var string = "Hello there";
var string1 = "Hello there again"
string = string.function();
string1 = string.function();
I am aware that this can be achieved by doing something like this function(string);, but I am a massive fan of more "inline code" and would like a nicer way to do it.
To achieve this you make your string variable an object
var string = {
text: "Hello there",
func: function(value) {
return value;
}
}
string.func(string.text); // Hello there
Edit: If you want your function to work on all strings add a method in String.prototype like so
String.prototype.your_function = function (char) {
// work on char here
return char
};
You can add custom functions to built in JavaScript object prototypes to your need.
For example in the case of your string approach, you can add a custom property to String.prototype like this:
String.prototype.myFunction = function() {
return 'Value from myFunction: ' + this.valueOf();
}
And when you declare a string you can go and call your new function inline:
var s = 'my string';
s.myFunction();
And it will return:
"Value from myFunction: my string"
Hope it helps!
I think this what you need
String.prototype.function = function ()
{
return this + " world";
};
var x = "hello";
var y = x.function();
console.log(y);

Are javascript object variables just reference type?

If you have a javascript variable that is an object and you make a new variable equal the the first variable, does it create a new instance of the object, or do they both reference the same object?
They always reference the same object. We can see that by trying the following:
var x = {foo:11};
var y = x;
y.foo = 42;
console.log(x.foo);
// will print 42, not 11
Object Reference explained!
Look the image for better understanding. When you create an object, suppose s1 it is having just a reference in the memory heap and now when you create another object say s2 and say s1 = s2 that means both the objects are actually pointing to the same reference. Hence when you alter either of them, both change.
Both will refer to the same object.
If you want to create a new instance:
var Person = function() {
this.eyes = 2,
this.hands = 2
};
var bob = new Person();
var sam = new Person();
Those two are different objects.
Here is the answer: when you create an object and then assign it to another it will refer to the same object.
Here is an example:
var hacker = {
name : 'Mr',
lastname : 'Robot'
};
console.log(hacker.name + '.' + hacker.lastname);
// Output Mr.Robot
// This variable is reference to hackers object
var anotherPerson = hacker;
console.log(anotherPerson.name + '.' + anotherPerson.lastname);
// Output Mr.Robot
// These will change hacker object name and lastname
anotherPerson.name = 'Elliot';
anotherPerson.lastname = 'Alderson';
console.log(anotherPerson.name + ' ' + anotherPerson.lastname);
// Output "Elliot Alderson"
// After it if you try to log object hacker name and lastname it would be:
console.log(hacker.name + '.' + hacker.lastname);
// Output "Elliot Alderson"
You can check the link here and play with it. It is not to complicated.
JSBIN Object Hacker
If you mean something like this
var a = { foo: "foo" };
var b = a;
then yes. They reference the same object.

Reference JS object through concatenation

I am trying to call an object.
The way I am currently doing it:
var key = object_0
The way I'd like to do it
var key = "object_" + questionId;
But when calling the concatenated object_0 I do not get the object info
when I do a:
console.log(key)
Any insight would be awesome.
Short answer: global scope + brackets.
window['object_'+questionId] = 'foo';
console.log(window['object_'+questionId]); // 'foo'
Long answer: Use dynamic variable names in JavaScript
If you use ES5 you can do so with creating new empty object. Here are the steps:
1.create empty object
var o = {};
2. use brackets to produce the new key on an object - ("object_" + questionId) - this will force the parser first to evaluate expression in the brackets
3.assign value to a newly added key
o[("object_" + questionId)] = XXX;
Then console.log(o) will output {object_0: XXX}
You can use the window object (access to global variables only):
var object_0 = { p: 42 },
questionId = 0,
key = "object_" + questionId;
document.write(window[key].p);
But i suggest to change the data structure to a more concise style:
var questions = { 200: { p: 42 }},
questionId = 200;
document.write(questions[questionId].p);

Can I refer to a variable using a string?

Say I have the following JS:
var foo_index = 123;
var bar_index = 456;
And the following HTML:
<div id="foo"></div>
<div id="bar"></div>
Then I'd like to say this:
thisIndex = this.id + '_index'
And I'd like thisIndex to be a number. How do I turn the string, which is exactly the variable name, into a variable?
You should put the variables in an object, like this:
var indices = {
foo: 123,
bar: 456
};
var thisIndex = indices[this.id];
This code uses JSON syntax an object literal to define an object with two properties and uses [] to access a property by name.
You can also write
var indices = new Object;
indices.foo = 123;
indices["bar"] = 456;
You can. If foo_index and bar_index are global variables, you can simply do:
var thisIndex = window[this.id + '_index'];
you can try using the eval function:
http://www.w3schools.com/jsref/jsref_eval.asp
it does exactly what you need.
window["myvar"] = 'hello';
alert(myvar);
To answer your question, you can use the eval function to evaluate a string:
thisIndex = eval(this.id + '_index');
However, using the eval function is generally a sign of badly constructed code. I think that you should use an associative array instead:
var numbers = { foo: 123, bar: 456 };
thisIndex = numbers[this.id];
I am not sure what do you want to achieve, but maybe this approach could be better (it depends on some factors like version of HTML you use as #Andy E points in comment below):
<div id="foo" index="123"></div>
<div id="bar" index="456"></div>
<script>
var fooIndex = document.getElementById("foo").getAttribute("index");
</script>
Here value of index is kept together with corresponding HTML element.
I think you want something like this:
// put your properties in an object of some kind
var dictionary =
{
foo_index: 123,
bar_index: 456
};
// you can set further properties with property syntax
dictionary.again_index = 789;
// or dictionary syntax - same result
dictionary['another_index'] = 012;
// then function to get the number value from the index name becomes
var thisIndex = Number(dictionary[this.id + '_index']);

Determine original name of variable after its passed to a function

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 })

Categories