2
    function f1(){
        var n=999;
        function f2(){
            alert(n); // 999
        }
    }

is the function f2() a closure? if not? why?

but in this post. How do JavaScript closures work? why it says:

function foo(x) {
  var tmp = 3;
  function bar(y) {
    alert(x + y + (++tmp));
  }
  bar(10);
}
foo(2)

That is not a closure.A closure is when you return the inner function. The inner function will close-over the variables of foo before leaving. why?

but i don't know what's the difference between the example i made and another i cited, one is not a closure.but one is. i think the two example is the same.

Community
  • 1
  • 1
runeveryday
  • 2,751
  • 4
  • 30
  • 44
  • What prompted this question? What answer were you expecting? More context will lead to better answers... – Cameron Jun 26 '11 at 02:17
  • Doesn't f1 need to be stored in a variable, or f2 need to be returned and that stored in a variable in order for it to truly be a closure? – b01 Feb 01 '12 at 17:03

2 Answers2

3

Yes, f2 is a closure, since it accesses a variable (n) from an outer scope. (OK, it's not really a closure -- see update below).

n was declared inside f1, not f2; this makes it belong to f1's scope. So when you create the function f2 which references n, it is a closure by definition, since it uses someone else's variable.

UPDATE

Alright, if I understand the answer you've linked to correctly, it says that f2 is not a closure because it is merely accessing a variable within its scope (just like an if statement, which gets its own scope within the braces*, can use variables from the outer scope without needing a closure).

* Update: Turns out that only functions get their own scope in Javascript, not any old blocks. But my point still stands...

However, f2 would become a closure if it left f1's scope (e.g. by being returned); in that case, it would still have access to f1's variable n, even though f1's original scope would no longer exist (it's exited when control leaves the function). f2 would have "closed over" f1's variables, thus artificially extending the lifespan of f1's scope.

Personally, I would still call f2 a closure, even if it never leaves f1. If a function can become a closure simply by being used outside of its declaring scope, and its behaviour inside that scope is no different whether it's technically a closure or not, then I see no point in making a distinction. I would even go so far as to say that it's an implementation detail whether f2 is a closure or not, if it never leaves f1's scope.

On the other hand, ignoring that distinction would mean that any function that uses a global variable would be called a "closure", since it accesses a variable from an outer scope. So the fact that it becomes a closure only when it leaves the scope(s) that the variables it is using are defined in is a worthwhile (albeit subtle) distinction.

I guess the clearest answer I can give is that it's not a closure yet.

Community
  • 1
  • 1
Cameron
  • 96,106
  • 25
  • 196
  • 225
  • i have updated my queston. there is an example like f2 function. but it says it's not a closure. thank you. – runeveryday Jun 26 '11 at 02:21
  • i am sorry, i am still really understand it well :) – runeveryday Jun 26 '11 at 03:05
  • 1
    @runeveryday: Picture the inside of an `if` block. Inside that block, you can declare variables that are visible only within that block (this is a scope). But you can read and modify variables that were declared within the function that encloses the `if` (one of the `if`'s outer scopes). That `if` is just like your `f2` function right up to that point. There is no closure. But if you return the `f2` function, or otherwise expose it outside of `f1` (something that cannot be done to `if`s since they are not objects), then `f2` can still access `n`, even though it was from `f1`! That's a closure. – Cameron Jun 26 '11 at 18:24
  • 1
    @runeveryday: In other words, when I first said that `f2` was a closure, I was wrong (at least technically). It is not a closure *until it leaves `f1`'s scope*. Only *then* is it a closure. In your example (and the one you linked to), the inner function never leaves the outer function's scope. So even though it uses variables from the outer function, it doesn't need to be a closure in order to do so (just like an `if`), *unless it leaves that outer function* -- in which case it turns into a closure around the variables that it references from the outer function/scope(s). Better? ;-) – Cameron Jun 26 '11 at 18:33
1

It is a closure, because it depends on the values of variables in an intermediate (i.e. not local or global) scope, and if the variable changes then so will the operation of the closure. That the value is always the same is incidental.

You may however want to return the closure to the caller of f1() so that it can be used elsewhere.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358