{"action":"created","issue":{"url":"https://api.github.com/repos/getify/You-Dont-Know-JS/issues/529","labels_url":"https://api.github.com/repos/getify/You-Dont-Know-JS/issues/529/labels{/name}","comments_url":"https://api.github.com/repos/getify/You-Dont-Know-JS/issues/529/comments","events_url":"https://api.github.com/repos/getify/You-Dont-Know-JS/issues/529/events","html_url":"https://github.com/getify/You-Dont-Know-JS/issues/529","id":104683917,"number":529,"title":"\"scope & closures\": Block Scoping Revisited - clarification of scope created by let (question)","user":{"login":"bl4de","id":3187617,"avatar_url":"https://avatars.githubusercontent.com/u/3187617?v=3","gravatar_id":"","url":"https://api.github.com/users/bl4de","html_url":"https://github.com/bl4de","followers_url":"https://api.github.com/users/bl4de/followers","following_url":"https://api.github.com/users/bl4de/following{/other_user}","gists_url":"https://api.github.com/users/bl4de/gists{/gist_id}","starred_url":"https://api.github.com/users/bl4de/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bl4de/subscriptions","organizations_url":"https://api.github.com/users/bl4de/orgs","repos_url":"https://api.github.com/users/bl4de/repos","events_url":"https://api.github.com/users/bl4de/events{/privacy}","received_events_url":"https://api.github.com/users/bl4de/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-09-03T12:47:21Z","updated_at":"2015-09-03T12:59:04Z","closed_at":null,"body":"Hi,\r\n\r\nI've got a question about scope created by _let_.\r\n\r\nWe've got an example (similar as in YDKJS):\r\n\r\n```javascript\r\n\"use strict\";\r\n\r\nfor (let a = 1; a < 10; a++) {\r\n    setTimeout( function() {\r\n        console.log(a);\r\n    }, 0);\r\n}\r\n```\r\n\r\nWorks perfect, closure in setTimeout() has access to valid _a_ in each iteration as is defined inside scope created by _let_.\r\n\r\nBut let's do something like this:\r\n\r\n```javascript\r\n\"use strict\";\r\nfunction foo() {\r\n    {\r\n        let b = 10;\r\n        for (let a = 1; a < 10; a++) \r\n        {\r\n            console.log(\"in loop: \", a);\r\n            fn();\r\n        }\r\n    }\r\n}\r\n    \r\nfoo();\r\n\r\nconsole.log(a);  // undefined\r\nconsole.log(b);  // Uncaught ReferenceError: b is not defined\r\n\r\nfunction fn() {\r\n    console.log(\"in fn(): \", a);\r\n}\r\n```\r\n\r\nI define fn() *outside* of scope created by _let_ (in _for_ statement). Also there's one more block scope created by outside brackets. _a_ should not be visible, right? And everything is enclosed in foo() which is created yet another scope.\r\n\r\nAnd the result is:\r\n> in loop:  1\r\nclosure2.js:20 in fn():  10\r\nclosure2.js:7 in loop:  2\r\nclosure2.js:20 in fn():  10\r\nclosure2.js:7 in loop:  3\r\nclosure2.js:20 in fn():  10\r\nclosure2.js:7 in loop:  4\r\nclosure2.js:20 in fn():  10\r\nclosure2.js:7 in loop:  5\r\nclosure2.js:20 in fn():  10\r\nclosure2.js:7 in loop:  6\r\nclosure2.js:20 in fn():  10\r\nclosure2.js:7 in loop:  7\r\nclosure2.js:20 in fn():  10\r\nclosure2.js:7 in loop:  8\r\nclosure2.js:20 in fn():  10\r\nclosure2.js:7 in loop:  9\r\nclosure2.js:20 in fn():  10\r\nclosure2.js:15 10\r\nclosure2.js:16 Uncaught ReferenceError: b is not defined\r\n\r\n_fn()_ has an access to _a_ as is called inside the scope, where _a_ is defined (right?). But how _a_ might be accessible outside of all scopes which surround it? (this line with console.log(a), where there's _undefined_ - as I was expecting Reference Error, the same as for _b_)\r\n\r\nAnd why _a_ in each iteration, printed by _fn()_, behaves as if _fn()_ was declared as closure, similar as in your example from \"Loops + Closure\" chapter?\r\n\r\nIs there's something I didn't I understand from scopes?\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/getify/You-Dont-Know-JS/issues/comments/137431554","html_url":"https://github.com/getify/You-Dont-Know-JS/issues/529#issuecomment-137431554","issue_url":"https://api.github.com/repos/getify/You-Dont-Know-JS/issues/529","id":137431554,"user":{"login":"getify","id":150330,"avatar_url":"https://avatars.githubusercontent.com/u/150330?v=3","gravatar_id":"","url":"https://api.github.com/users/getify","html_url":"https://github.com/getify","followers_url":"https://api.github.com/users/getify/followers","following_url":"https://api.github.com/users/getify/following{/other_user}","gists_url":"https://api.github.com/users/getify/gists{/gist_id}","starred_url":"https://api.github.com/users/getify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getify/subscriptions","organizations_url":"https://api.github.com/users/getify/orgs","repos_url":"https://api.github.com/users/getify/repos","events_url":"https://api.github.com/users/getify/events{/privacy}","received_events_url":"https://api.github.com/users/getify/received_events","type":"User","site_admin":false},"created_at":"2015-09-03T12:59:04Z","updated_at":"2015-09-03T12:59:04Z","body":"IIUC the only explanation for this is that in whatever environment you're trying this in, there's already an `a` in the outer scope, diff from the `a` in the loop. Or whatever implementation you're running in has a massive bug. `a` most definitely should not be accessible in that scope."}}