Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>It's actually a very interesting area of Javascript. Details in <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm" rel="noreferrer">the spec</a>, but: Javascript's way of handling local variables is quite different from the way C does it. When you call a function, amongst other things a "variable environment" for that call is created, which has something called a "binding object". (Call it the "variable object" for short; saying "the binding object of the variable environment" is just a <em>tad</em> bit long-winded!) The variable object has <em>properties</em> for the arguments to the function, all local variables declared in the function, and all functions declared within the function (along with a couple of other things). Unqualified references (e.g., the <code>foo</code> in <code>foo</code>, not <code>obj.foo</code>) within the function are first checked against the variable object to see if they match properties on it; if they do, those properties are used.</p> <p>When a closure survives the function returning (which can happen for several reasons), the variable object for that function call is <em>retained</em> in memory by the reference from the closure. At first glance, that would suggest that the stack isn't used for local variables; in fact, modern JavaScript engines are quite smart, and may (if it's worthwhile) use the stack for locals that aren't actually used by the closure. (Naturally, the stack is still used for keeping track of return addresses and such.)</p> <p>Here's an example:</p> <pre><code>function foo(a, b) { var c; c = a + b; function bar(d) { alert("d * c = " + (d * c)); } return bar; } var b = foo(1, 2); b(3); // alerts "d * c = 9" </code></pre> <p>When we call <code>foo</code>, a variable object gets created with these properties:</p> <ul> <li><code>a</code> and <code>b</code>&nbsp;&mdash; the arguments to the function</li> <li><code>c</code>&nbsp;&mdash; a local variable declared in the function</li> <li><code>bar</code>&nbsp;&mdash; a function declared within the function</li> <li>(...and a couple of other things)</li> </ul> <p>When <code>foo</code> executes the statement <code>c = a + b;</code>, it's referencing the <code>c</code>, <code>a</code>, and <code>b</code> properties on the variable object for that call to <code>foo</code>. When <code>foo</code> returns a reference to the <code>bar</code> function declared inside it, <code>bar</code> survives the call to <code>foo</code> returning. Since <code>bar</code> has a (hidden) reference to the variable object for that specific call to <code>foo</code>, the variable object survives (whereas in the normal case, it would have no outstanding references and so would be available for garbage collection).</p> <p>Later, when we call <code>bar</code>, a <em>new</em> variable object for that call is created with (amongst other things) a property called <code>d</code>&nbsp;&mdash; the argument to <code>bar</code>. Unqualified references within <code>bar</code> are first checked against the variable object for that call; so for instance, <code>d</code> resolves to the <code>d</code> property on the variable object for the call to <code>bar</code>. But an unqualified reference that doesn't match a property on its variable object is then checked against the next variable object in the "scope chain" for <code>bar</code>, which is the variable object for the call to <code>foo</code>. And since that has a property <code>c</code>, that's the property used within <code>bar</code>. E.g., in rough terms:</p> <pre>+----------------------------+ | `foo` call variable object | | -------------------------- | | a = 1 | | b = 2 | | c = 3 | | bar = (function) | +----------------------------+ ^ | chain | +----------------------------+ | `bar` call variable object | | -------------------------- | | d = 3 | +----------------------------+</pre> <p>Implementations are free to use whatever mechanism they want under the covers to make the above <em>seem</em> to happen. It's impossible to get direct access to the variable object for a function call, and the spec makes clear that it's perfectly fine if the variable object is just a concept, rather than a literal part of the implementation. A simple implementation may well just literally do what the spec says; a more complicated one may use a stack when there are no closures involved (for the speed benefit), or may always use a stack but then "tear off" the variable object needed for a closure when popping the stack. The only way to know in any specific case is to look at their code. :-)</p> <p>More about closures, the scope chain, etc. here:</p> <ul> <li><em><a href="http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html" rel="noreferrer">Closures are not complicated</a></em></li> <li><em><a href="http://blog.niftysnippets.org/2008/03/poor-misunderstood-var.html" rel="noreferrer">Poor misunderstood 'var'</a></em></li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload