0

Is it possible to implement the "iterate" function (below) that iterates it's own variables that's not using deprecated JavaScript functionality?

(function () {
    var a = 1;
    var b = 2;
    var iterate = function () {
        var k;
        for (k in this) {     //WRONG IMPLEMENTATION!
            alert(this[k]);
            // a
            // b
            // iterate
        }
    };
}).call(this);

I set a breakpoint inside "iterate" and poked around in the debugger and was not able to figure out how to access the other variable names. Also, after perhaps dozens of Google searches I've not been able to find an answer as the search hits usually refer to an external not internal perspective.

UPDATE: I got properties and variables confused. Before editing, the original question was asking about iterating the properties. I now realize those are variables.

Pete Alvin
  • 4,646
  • 9
  • 39
  • 56
  • 3
    I wouldn't call those "properties". They are local variables. – Thilo Nov 19 '14 at 00:08
  • 1
    You will need to [distinguish between variables and properties](http://stackoverflow.com/q/13418669/1048572). Properties are iterable with `Object.getOwnPropertyNames`, variables are not. – Bergi Nov 19 '14 at 00:44
  • possible duplicate of [How do I enumerate the properties of a javascript object?](http://stackoverflow.com/questions/85992/how-do-i-enumerate-the-properties-of-a-javascript-object) – Alex Nov 19 '14 at 09:30
  • @Pinal, not a duplicate of that. – Pete Alvin Nov 19 '14 at 17:50
  • I updated the question title. – Pete Alvin Nov 19 '14 at 18:07
  • 1
    @PeteAlvin Perhaps you could update the question to clarify that you want to iterate over all in-scope variables (and not those belonging to an object)? It seems several of us had the same misunderstanding. – Andrew Miner Nov 19 '14 at 18:07

3 Answers3

2

No. Besides horrendous eval hacks you cannot access variables in any scope but the global scope (window) or an object's scope (this) in a dynamic way.

But you don't need to! If you want dynamic access to those variables, store them in an object:

var data = {
    a: 1,
    b: 2
};
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • Thanks, yes I realized I could create a local object, perhaps with a short name like "o" and access like o.a and o.b. I was hoping to eliminate the o. scoping syntax. Looks like I'm out of luck. – Pete Alvin Nov 19 '14 at 17:54
0

I believe you want hasOwnProperty. Every object has this method whereby you can pass it a property name (i.e., what you get from iterating with a for loop) and learn whether that property is set on the given object (and therefore isn't inherited). So, for example:

for (var k in this) {
    if (this.hasOwnProperty(k)) {
        // do something here...
    }
}

You might also want to look into Underscore.js which has a ton of useful shortcuts for this and many similar tasks.

Update

I think I may have misunderstood the question... if you wanted to know whether there's a way to iterate over all in-scope variables, then: no, there isn't.

Andrew Miner
  • 5,587
  • 2
  • 22
  • 26
0

Try

var j = (function (obj) {

        var a = 1;
        var b = 2;

        var iterate = function () {
            var k;
            for (k in this) {     
                console.log(k, this[k]);
            };
        }.bind(obj);
         obj["a"] = a; obj["b"] = b; obj["iterate"] = iterate;

       return obj
    }(Object.create(null))) || obj;

var j = (function (obj) {
        
        var a = 1;
        var b = 2;
        
        var iterate = function () {
            var k;
            for (k in this) {     
                console.log(k, this[k]);
            };
        }.bind(obj);
         obj["a"] = a; obj["b"] = b; obj["iterate"] = iterate;
        
       return obj
    }(Object.create(null))) || obj;
    
    j.iterate();
    j.a = 5;
    j.iterate();
    console.log(j)
guest271314
  • 1
  • 15
  • 104
  • 177
  • It looks like it's theoretically possible, but not "convenient." The goal was to iterate without explicit programming the variable names. But thank you for providing a solution! – Pete Alvin Nov 19 '14 at 17:57