JavaScript: lexical closure or something else?

javascript

Solution

Check out http://jibbering.com/faq/notes/closures/.

It will explain the "something else" and probably all you'll ever want to know about how JavaScript variables and scopes work. JavaScript uses "execution context" closures, not "lexical variable" closures (edit: it is still a lexical binding, just not necessarily as expected -- see below).

In the first example, the same `obj` was bound three times or rather, the same `obj` property (edit: the specification doesn't require this, but calling it a property is one way to explain it) of the single bound execution context is shared!

`var` does not "declare" a variable (edit: it is an annotation that applies to an entire scope and is not affected by {}'s, excepting the following) and `function` is how one can introduce new scopes -> new execution contexts (which is why the 2nd example works as expected). New scopes are only introduced with `function` (or `eval`/similar).

Happy coding.

Problem

Consider this script: ``` function Obj(prop) { this.prop = prop; } var NS = { strings: ['first','second','third'], objs: [], f1: function() { for (s in this.strings) { var obj = new Obj(this.strings[s]); obj.f2 = function() { alert(obj.prop); } this.objs.push(obj); } } } NS.f1(); NS.objs[0].f2(); // third NS.objs[1].f2(); // third NS.objs[2].f2(); // third ``` Not exactly the expected output, however when I update to this: ``` function Obj(prop) { this.prop = prop; } var NS = { strings: ['first','second','third'], objs: [], f1: function() { for (s in this.strings) { var obj = new Obj(this.strings[s]); this.wire(obj); // replaces previous function def this.objs.push(obj); } }, wire: function(obj) { obj.f2 = function() { alert(obj.prop); } // exact same code and function def as the first example } } NS.f1(); NS.objs[0].f2(); // first NS.objs[1].f2(); // second NS.objs[2].f2(); // third ``` This seems to work, and I've no idea why. Can anybody enlighten me? Thanks

Original source