107

I want to use the value of a variable to access an object.

Let's say I have an object named myobject.

I want to fill a variable with this name and use the variable to access the object.

Example:

var objname = 'myobject';
{objname}.value = 'value';

14 Answers 14

138

Global:

myObject = { value: 0 };
anObjectName = "myObject";
this[anObjectName].value++;

console.log(this[anObjectName]);

Global: v2

var anObjectName = "myObject";
this[anObjectName] = "myvalue"

console.log(myObject)

Local: v1

(function() {
    var scope = this;

    if (scope != arguments.callee) {
        arguments.callee.call(arguments.callee);
        return false;
    }

    scope.myObject = { value: 0 };
    scope.anObjectName = "myObject";
    scope[scope.anObjectName].value++;

    console.log(scope.myObject.value);
})();

Local: v2

(function() {  
    var scope = this;

    scope.myObject = { value: 0 };
    scope.anObjectName = "myObject";
    scope[scope.anObjectName].value++;

    console.log(scope.myObject.value);    
}).call({});
Sign up to request clarification or add additional context in comments.

8 Comments

@Shaz -- both of those reference the same scope actually ;-) (Assuming they are executed in a browser.) alert(this === window).
@PeeHaa - The Local example sets a variable on the window object called objname which is then referenced via this ... you could substitute window for this in the second example and everything would still work. :-)
@SeanVieira: Take a look at the updated example. Hopefully this works correctly now.
@Shaz -- arguments.callee is deprecated, but it's a very clever implementation nonetheless -- and it doesn't litter the global scope. +1
It may not be polluting the global scope, but it's creating an object that is shared by every invocation of the function. Your function is holding objname as a property of the function itself. It can fail for recursive functions. Not sure how this can be used in the real world.
|
46

Use square bracket around variable name.

var objname = 'myobject';
{[objname]}.value = 'value';

2 Comments

This throws an exception: SyntaxError: expected expression, got '.'. It does not work; why so many upvotes?
This is what I was searching for!
10

Is it a global variable? If so, these are actually part of the window object, so you can do window[objname].value.

If it's local to a function, I don't think there's a good way to do what you want.

Comments

9

The object exists in some scope, so you can almost always access the variable via this syntax:

var objname = "myobject";
containing_scope_reference[objname].some_property = 'some value';

The only place where this gets tricky is when you are in a closed scope and you want access to a top-level local variable. When you have something like this:

(function(){
    var some_variable = {value: 25};
    var x = "some_variable";
    console.log(this[x], window[x]); // Doesn't work
})();

You can get around that by using eval instead to access the current scope chain ... but I don't recommend it unless you've done a lot of testing and you know that that's the best way to go about things.

(function(){
    var some_variable = {value: 25};
    var x = "some_variable";
    eval(x).value = 42;
    console.log(some_variable); // Works
})();

Your best bet is to have a reference to a name in an always-going-to-be-there object (like this in the global scope or a private top-level variable in a local scope) and put everything else in there.

Thus:

var my_outer_variable = {};
var outer_pointer = 'my_outer_variable';
// Reach my_outer_variable with this[outer_pointer]
// or window[outer_pointer]

(function(){
    var my_inner_scope = {'my_inner_variable': {} };
    var inner_pointer = 'my_inner_variable';
    // Reach my_inner_variable by using
    // my_inner_scope[inner_pointer]
})();

Comments

8

You could use eval:

eval(variablename + ".value = 'value'");

6 Comments

Isn't eval considered evil? If not I might use it. Because it is a global right now but I wanted to move it into a function to clean up stuff.
Lol. If the variable name comes from user input, make sure you validate it, so that it doesn't contain any JS code that eval can execute.
This is one of the few legitimate uses of eval, in my opinion. We have to make sure the variable is clean, though.
Yes it's not really a problem. But take a look at the answer from Shaz. I think that's a more clean solution.
@PeeHaa: If you're considering moving it, why not move it into a property of a known object, so you can do something like myVar[objname].value?
|
6

You can't do this in general, except at the window scope, where you can write window[objname].value = 'value';

Comments

5

Square brackets can be used to make key dynamic like this

var myObjKey = "key";

var obj = {[myObjKey] : "value" };
console.log(obj); // => {key: 'value'}

var anotherObj = {["justString"] : "value" };
console.log(anotherObj ); // => {justString: 'value'}

Comments

4

I think Shaz's answer for local variables is hard to understand, though it works for non-recursive functions. Here's another way that I think it's clearer (but it's still his idea, exact same behavior). It's also not accessing the local variables dynamically, just the property of the local variable.

Essentially, it's using a global variable (attached to the function object)

// Here's  a version of it that is more straight forward.
function doIt() {
    doIt.objname = {};
    var someObject = "objname";
    doIt[someObject].value = "value";    
    console.log(doIt.objname);
})();

Which is essentially the same thing as creating a global to store the variable, so you can access it as a property. Creating a global to do this is such a hack.

Here's a cleaner hack that doesn't create global variables, it uses a local variable instead.

function doIt() {
  var scope = {
     MyProp: "Hello"
  };
  var name = "MyProp";
  console.log(scope[name]);
}

See Javascript: interpret string as object reference?

Comments

3
let players = [];
players[something] = {};
players[something].somethingElse = 'test';
console.log(players); 

-> [ something: { somethingElse: 'test' } ];

Comments

1

If object is in some namespace ie. Company.Module.Components.Foo you can use this function:

CoffeeScript:

objByName: (name, context = window) ->
    ns = name.split "."
    func = context
    for n, i in ns
        func = func[n]
    return func

Resulted Js:

objByName: function(name, context) {
  var func, i, n, ns, _i, _len;
  if (context == null) {
    context = window;
  }
  ns = name.split(".");
  func = context;
  for (i = _i = 0, _len = ns.length; _i < _len; i = ++_i) {
    n = ns[i];
    func = func[n];
  }
  return func;
}

Then you can create a new object or do whatever. Note the parenthises through.

var o = new (objByName('Company.Module.Components.Foo'))
objByName('some.deeply.nested.object').value

This idea is borrowed from similar question: How to execute a JavaScript function when I have its name as a string

Comments

0

One of the challenges I had with the answers is that it assumed that the object was a single level. For example,

const testObj = { testKey: 'testValue' }
const refString = 'testKey';
const refObj = testObj[refString];

works fine, but

const testObj = { testKey:
                  { level2Key: 'level2Value' }
                }
const refString = 'testKey.level2Key';
const refObj = testObj[refString];

does not work.

What I ended up doing was building a function to access multi-level objects:

objVar(str) {
    let obj = this;
    const parts = str.split('.');
    for (let p of parts) {
        obj = obj[p];
    }
    return obj;
}

In the second scenario, then, I can pass the string to this function to get back the object I'm looking for:

const testObj = { testKey:
                  { level2Key: 'level2Value' }
                }
const refString = 'testObj.testKey.level2Key';
const refObj = objVar[refString];

Comments

0

You can set an objects property this way:

var obj = {};
obj.whateverVarName = 'yourVal';
console.log(obj);

Comments

0

If you already know the list of the possible varible names then try creating a new Object(iconObj) whose properties name are same as object names, Here in below example, iconLib variable will hold two string values , either 'ZondIcons' or 'MaterialIcons'. propertyName is the property of ZondIcons or MaterialsIcon object.

   const iconObj = {
    ZondIcons,
    MaterialIcons,
  }
  const objValue = iconObj[iconLib][propertyName]

Comments

-1

When using the window[objname], please make sure the objname is global variables. Otherwise, will work sometime, and fail sometimes. window[objname].value.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.