8

Is it possible to set a variable by concatenating two strings together to form the name?

If at all possible I'd like to determine what variable to set based on the class names of the objects that the user clicks. I know I can hard code a bunch of if/else if statements, but it would be really cool if I could reference the variables indirectly. I was thinking something like this:

var owner_read;
var group_read;

function setVariableIndirectly(object){
    var second = object.className; // returns "read"
    var first = object.parentElement.className; // returns "group"

    first + "_" + second = "set this as the new variable";
}

Is there any way of doing this??

EDIT:

Here's the html that the data is coming in from.

<p class="owner">
    <span class="read" onclick="permissionClick(this)">r</span>
    <span class="write" onclick="permissionClick(this)">w</span>
    <span class="execute" onclick="permissionClick(this)">x</span>
</p>
Chris Schmitz
  • 20,160
  • 30
  • 81
  • 137
  • There are no *variables* with "dynamic names" in JavaScript (excluding `eval` and `new Function` shenanigans); what there is, are *properties* (of objects) with "dynamic names". I would avoid using `window` as such a container to avoid clashes (and you *will* find these!) and mitigate "global pollution", but instead use properties of some [internal] object. – user2864740 Oct 31 '13 at 03:08

3 Answers3

12

This is possible but you have to be wary of context and scope.

1. To set variable with global scope in browser environment:

window[str1 + str2] = value

2. To set variable with global scope in node environment:

global[str1 + str2] = value

3. Within a closure and scoped within that closure:

this[str1 + str2] = value

Within the closure, global and window will still set the global. Note that if you are within a function that is being called, 'this' could refer to another object.

Brian Peacock
  • 711
  • 8
  • 20
7

It's not clear exactly what you're trying to accomplish, but you can access variables by name as properties of an object.

// this is the container to hold your named variables 
//    (which will be properties of this object)
var container = {};

function setVariableIndirectly(obj){
    var second = obj.className; // returns "read"
    var first = obj.parentNode.className; // returns "group"

    // this is how you access a property of an object 
    //    using a string as the property name    
    container[first + "_" + second] = "set this as the new variable";

   // in your example container["read_group"] would now be set
}

It's probably better to put your variables on your own container object as shown above, but you can also access global variables via properties on the window object.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Perfect!! Sorry if I wasn't clear in the description. I'll edit my original post, the html makes it a bit more clear. – Chris Schmitz Oct 31 '13 at 03:19
  • @ChrisSchmitz - FYI, you probably want to use an attribute like `data-permissiontype="read"` attribute rather than `class="read"` because the way you have it, you can't use any other classes for styling purposes. – jfriend00 Oct 31 '13 at 03:26
  • Ah, very good point. Thanks again! – Chris Schmitz Oct 31 '13 at 03:29
2

You can set a global variable this way:

window[first + "_" + second] = "set this as the new variable";

and access it as:

console.log(group_read);
Gaurav
  • 12,662
  • 2
  • 36
  • 34
  • I do not recommend using `window[..]` as a demonstration due to it's inherent side-effects. Once properties are understood - and that `window` is just an object, and how JavaScript resolves identifiers - the rest just falls into place. – user2864740 Oct 31 '13 at 03:11