0

Does JavaScript have a variable for items declared in the function's scope? I would like to access items declared inside a function using an associative array.

For example I can do the following with items at the global scope

    var globalVar = "hi";
    var myFunction = function () {
        alert(window["globalVar"]);
    };

But I would like to do a similar thing with variables declared inside a function

    var myFunction = function () {
        var funcVar = "hi";
        alert(func["funcVar"]);
    };

I realise doing such a thing isn't necessarily a good thing and I am doing the below instead, but I am still interested if JavaScript has such a variable.

    var myFunction = function () {
        var func = {funcVar : "hi" };
        alert(func["funcVar"]);
    };
row1
  • 5,568
  • 3
  • 46
  • 72

4 Answers4

3

This question has been asked and answered many times. No, in JavaScript there is no local object containing local variables as properties (in the way that for instance, in browser environments the window object contains global variables as properties).

Depending on what you are trying to accomplish, there are probably many alternative ways to attack it, including the one you are using now.

Duplicate of Javascript: Get access to local variable or variable in closure by its name, How can I access local scope dynamically in javascript?, Javascript local variable declare.

Community
  • 1
  • 1
  • 1
    Please flag it as a duplicate then. I did search for it, but got lost amongst a bunch of topics talking about function scope. – row1 May 16 '13 at 04:36
2

Perhaps you could assign properties to the function object itself, and reference those?

var myFunction = function() {
    myFunction.funcVar = 'hi';
    alert(myFunction['funcVar']);
};

It is not exactly the answer to your question, but it's the best way I can think of to access local variables as properties of an object. Note that in this method these variables will be visible outside the function in the same manner (that is, looking up the properties of the function).

If you really needed those properties to be hidden, you could hide them within a closure, like so:

var myFunction = function() {
    (function hidden() {
        hidden.funcVar = 'hi';
        alert(hidden['funcVar']);
    })();
};
Alec Henninger
  • 360
  • 3
  • 12
1

Functions are just special objects that can be invoked. You can set properties of a function, and get them later.

var a = function () {
    alert(a.testingVar);
};

a.testingVar = "asdf";

a();

DEMO: http://jsfiddle.net/gEM7W/

Although I don't see a reason/need to do this. You could always use a closure to keep local variables specific to a function. For example:

var a = (function () {
    var obj = {
        testingVar: "asdf"
    };
    return function () {
        alert(obj.testingVar);
    };
})();

a();

DEMO: http://jsfiddle.net/gEM7W/1/

Ian
  • 50,146
  • 13
  • 101
  • 111
0

You don't really have associative arrays. You have indexed arrays and you have objects.

In the future, there will be an iterator which will happily traverse both, without any side-effects. At that point, perhaps people will forget the difference.

However, the properties still wouldn't be order-based:

$arr = array(0, 1, "name"=>"Bob", 3);

In another language might get you an array where the keys are: 0, 1, "name", 3
In JS, you'd get 0, 1, 2, "name" (or "name", 0, 1, 2).

So stick with indexed arrays and objects with properties.

That said, you've got multiple options.

var myFunc = function () {
    var private_data = {
        name : "Bob",
        age : 32
    };

    return {
        getName : function () { return private_data.name; /* or private_data["name"] if that's really what your heart longs for */ },
        get : function (key) { return private_data[key] || null; },
        set : function (key, val) { private_data[key] = val; }
    };
};

Now everything is private, and you can access them by property-name, using dot or bracket notation.

If they can be public, and the function is always going to be called the same thing (ie: not a constructor making an instance) then you can attach yourself to the actual function:

var myFunc = function () {
    myFunc.name = "Bob";
    myFunc["age"] = 32;


    return {
        get : function (key) { return (myFunc.hasOwnProperty(key)) ? myFunc[key] : null; }
    };
};

Downside (or upside) is that myFunc is the public name. As such, these properties are publicly accessible.

Going the first route, you don't even need to declare a variable. You can just use the object you pass into a function.

var myFunc = function (dataObj) {
    return {
        getName : function () { return dataObj.name; },
        setAge  : function (val) { dataObj["age"] = val; }
    };
};

var bob = myFunc({ name : "Bob" });
bob.setAge(32);

Now everything's private and I didn't even have to declare anything.
Closure keeps the object in play as long as there's a publicly accessible function that's returned, which still has access to that particular instance of the function call.

Once you figure out closures, this becomes a non-issue.

Norguard
  • 26,167
  • 5
  • 41
  • 49
  • I appreciate the effort gone into this answer, but I am not sure how it answer my question. – row1 May 16 '13 at 04:34
  • @row1 Well, aside from "no", there are options, depending on what it is you're actually trying to ***do*** with the values. Are you trying to replicate OO-encapsulation? Are you trying to iterate through variables in the current scope? Are you trying to iterate/access them from an outer scope through closure? There's obviously a reason you care about this, rather than just: "Does it exist". And while attaching properties to an object is the first step to solving that, what's your second or third step? If you aren't doing anything with it, anyway, then why care to ask? – Norguard May 16 '13 at 04:42
  • My question contains pretty much exactly what I am trying to do and also contains a solution that I am happy with. I am just wondering if there is a special built-in variable for functions (like there is arguments) that I might be missing. – row1 May 16 '13 at 04:53
  • There is/are. We just have no access to them from within the language, much the same way as we haven't had access to properties which allow freezing/immutability or enumeration / etc of properties, despite them being part of the language from a JS-engine implementation perspective. Consumer-side... ...nope. But that's what the different patterns are for. – Norguard May 16 '13 at 04:58