3 ms·
I asked on the author’s site as well, but I don’t understand the argument that JavaScript doesn’t have lexical scoping. http://c2.com/cgi/wiki?LexicalScoping h
by danielparks 13y ago
I asked on the author’s site as well, but I don’t understand the argument that JavaScript doesn’t have lexical scoping.
http://c2.com/cgi/wiki?LexicalScoping http://c2.com/cgi/wiki?LexicalScoping
- cobbal 13y agoIt probably refers to the fact that variables by default are global. If you prefix them with var they're function scoped, but there's no way to make them local to the curly braces of an "if" statement. In scheme, lexical scoping is easily accomplished through the let form, and it's pretty hard to make a variable global by mistake. So yes it does have lexical scoping in the sense that function arguments are lexically scoped, but that's the only scoping environment, and you can't hide that fact behind macros like you could in scheme if it was needed.
- hayksaakian 13y agoDid you notice that "let" is coming in through ecmascript? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- deleted 13y ago[deleted]
- mistercow 13y ago>If you prefix them with var they're function scoped, but there's no way to make them local to the curly braces of an "if" statement. There is; it's just ugly. You just have to use an immediate function as the body of the if statement.
- djKianoosh 13y agoin the words of will smith in men in black, "please keep that kinda shi* to yourself"
- mistercow 13y agoI don't understand what you're trying to say, but I was describing a common and useful pattern.
- deleted 13y ago[deleted]
- djKianoosh 13y agoi was complimenting you.. ahh nevermind
- danielparks 13y agoThat’s roughly what I was thinking, but it seemed a little ridiculous to me — Javascript has lexical scoping, it’s just not required. It seems like this argument conflates lexical scoping with the requirement that variables be lexically scoped. Lexical scoping (even if optional) is extremely useful for closures. Requiring lexical scoping would very useful for safety.
- munificent 13y agoJavaScript doesn't have complete lexical scope. Consider: function foo() { console.log(whereDidThisComeFrom); } window.whereDidThisComeFrom = "the damn global object"; foo(); And: function foo() { var a = { whereDidThisComeFrom: "a, of all places" }; with (a) { console.log(whereDidThisComeFrom); } } foo(); In both cases, you can't lexically resolve the identifier whereDidThisComeFrom.
- ufo 13y agoIn the first case the lack of a whereDidThisComeFrom declaration in scope would imply that it meant `window.whereDidThisComeFrom` (in normal mode) or would imply a reference error (in strict mode) wouldn't it. Lua does the same thing and I never saw anyone complain about its lexical scoping.
- kragen 13y agoScheme does the same thing too: scheme@(guile-user)> (define (foo) (write where-did-this-come-from)) ;;; <stdin>:1:14: warning: possibly unbound variable `where-did-this-come-from' scheme@(guile-user)> (define where-did-this-come-from "the damn global scope") scheme@(guile-user)> (foo) "the damn global scope"scheme@(guile-user)> Munificent's assertion that this doesn't represent lexical scoping is wrong, but his assertion in another thread that with() is an exception to lexical scoping is correct, and therefore JS is not lexically scoped, just mostly lexically scoped.
- anonymoushn 13y agoI assume he means that Javascript has lexical scope at the function level, rather than at the block level. It is much nicer at the block level, both for human users of the language and for optimizing JITs.
- danielparks 13y agoAh, right, cobbal mentioned this, too. I hadn’t thought of that — I’m used to languages without that feature. (To be strict, that seems to be more a matter of what a scope is, rather than if the scoping is lexical or dynamic.)
- ufo 13y agoJavascript has C syntax but does not follow the C tradition of having one scope per block, instead having one scope per function. This is really unintuitive if you are used to how lexical scoping is done in other C-like languages and is the source of many common annoyances, like the closures-in-for-loops bug or needing to wrap your code in IIFEs[1] if you want to create a local scope or prevent variables from being global. [1] - Immediately Invoked Function Expressions: (function(){ ... }())
- munificent 13y agoLexical block scope is broken in (at least) three ways in JS: the global object and with() break lexical scoping, and hoisting breaks block scoping. Strict mode in ES 5 does address the first two, and "let" in ES 6 addresses the latter, so that's good. But at that point, you're talking about the future and not JavaScript as it is today.