Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is this example in the book really a closure or just global scope reference? #1727

Closed
akasuv opened this issue Mar 9, 2021 · 7 comments
Closed
Labels

Comments

@akasuv
Copy link

akasuv commented Mar 9, 2021

Yes, I promise I've read the Contributions Guidelines (please feel free to remove this line).


Please type "I already searched for this issue": I already search for this issue

Edition: 2nd

Book Title: Scope & Closures

Chapter: Chapter 7: Using Closures

Section Title: Live Link, Not a Snapshot

Question: variable studentName and function greeting() are both in the global scope, so when greeting() invoked, is studentName in greeting a closure reference or just global scope lookup?

Example in the book:

var studentName = "Frank";

var greeting = function hello() {
    // we are closing over `studentName`,
    // not "Frank"
    console.log(
        `Hello, ${ studentName }!`
    );
}

// later

studentName = "Suzy";

// later

greeting();
// Hello, Suzy!
@getify
Copy link
Owner

getify commented Mar 9, 2021

Both.

@akasuv
Copy link
Author

akasuv commented Mar 9, 2021

Hi, @getify, thanks for your reply! I can understand why it's a global scope lookup, but the closure part seems a little bit confusing, like you said in the book, one of conditions being a closure is:

Must be invoked in a different branch of the scope chain from the variable(s)

studentName and greeting are in the same scope branch which is global, and greeting() is also invoked on global scope, isn't it just a normal global scope lookup?

@getify
Copy link
Owner

getify commented Mar 9, 2021

Here's the relevant perspective to consider:

  1. If I were to take that snippet and do nothing else to it but wrap it in an outer scope (block, function, or module)... wouldn't we say that nothing had changed about its behavior? And if nothing changed about its behavior, isn't it fair to say that its nature (the how of its workings) is also the same (in spirit, if not in fact)?

    Such an alternate version of that code being contemplated is unquestionably closure. So the global-scope-only version is, in spirit, also closure. It's not terribly helpful to create this exception in your mind where code in the global scope cannot be closure when if the exact same code appeared elsewhere, it would be closure.

  2. The example in question is a very narrow example to illustrate an isolated point. I could have gone to the trouble of wrapping an outer scope around it to force a closure context... but what's the point of that? It creates unnecessary noise for no real benefit.

  3. Moreover, mathematically, it's a closure. IOW, in theory, it's a closure. In practice, the engines may or may not use the same mechanism or an exception path. Who knows?

It is true that in my courses and books, I do argue that closure which isn't observably different from the absence of closure is not really closure. IOW, theoretical but unobservable expressions of closure aren't terribly useful to us programmers; they're academic trivia.

While I stand by that in general, that's not really as much a claim about identity; rather it's more a claim about utility. An example of closure that's indistinguishable from global scope is not a particularly useful closure example. But that's not as strong a claim as "this is absolutely not closure in any way."

The example in question is a weak/useless example of closure, but in theory and spirit, if not practice, it's still a closure, as opposed to the contrary absolute claim of it not being a closure at all -- a claim I'm not willing to make.

@perioad
Copy link

perioad commented Sep 10, 2021

Hello @getify :)
Could you please illustrate with code your point? It would be so helpful!

If I were to take that snippet and do nothing else to it but wrap it in an outer scope (block, function, or module)

@getify
Copy link
Owner

getify commented Feb 4, 2022

@perioad

This quoted code above:

var studentName = "Frank";

var greeting = function hello() {
    // we are closing over `studentName`,
    // not "Frank"
    console.log(
        `Hello, ${ studentName }!`
    );
}

// later

studentName = "Suzy";

// later

greeting();
// Hello, Suzy!

...becomes this code with an outer scope wrapped around it (via an IIFE):

(function OuterScopeIIFE(){

   var studentName = "Frank";

   var greeting = function hello() {
       // we are closing over `studentName`,
       // not "Frank"
       console.log(
           `Hello, ${ studentName }!`
       );
   }

  // later

   studentName = "Suzy";

   // later

   greeting();
  // Hello, Suzy!

})();

@getify getify added the question label Feb 4, 2022
@getify getify closed this as completed Feb 4, 2022
@perioad
Copy link

perioad commented Feb 11, 2022

@getify
Thanks for finding the time and answering my question! It makes much more sense for me now. Cheers!

@haoyi2015
Copy link

haoyi2015 commented Feb 11, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants