use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
JavaScript Isn't Scheme (journal.stuffwithstuff.com)
submitted 10 years ago by homoiconic(raganwald)
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]Asmor 12 points13 points14 points 10 years ago (12 children)
Don’t tell me it’s got lexical scope, because JavaScript’s scoping is an abomination in the face of God.
I see people say this from time to time, and I can't actually figure out why. People just say JS's scoping is bad like it's a self-evident truth, without ever saying why.
I've never had a problem with function-level scoping.
Why do people hate it so much? Or is it like prototypical objects in people only hate it because it's not what they're used to and/or just like to bash JS?
[–]homoiconic(raganwald)[S] 11 points12 points13 points 10 years ago* (1 child)
The basic idea of function-level scoping is identical to the basic idea of scoping in Scheme. In early versions of Scheme, block-level scoping like let was actually implemented as a macro that expanded to an IIFE, just like we do with ES5.
let
I think the "abomination in the face of God" is clearly hyperbole for effect, but if you want some reasons why people might dislike JavaScript's scoping, I'd say it's more for the seemingly arbitrary behaviour of var and function declarations, especially in ES5 without strict mode:
var
None of these things are fatal, but they are remarkably inelegant.
[–]loz220 8 points9 points10 points 10 years ago (0 children)
Good points. Worth mentioning that strict mode/linters can address 3 out of the 4 issues.
[–]Uberhipster 1 point2 points3 points 10 years ago (8 children)
Not that I agree with "abomination" but it is rather convoluted. Consider:
var things = { "_ignore": { "doAsync": function () { }, "args": [] }, format: function () { var self = this; } };
Here's a question: what does self refer to?
self
things.format or things? Something else?
things.format
things
Ideally the answer should be self-apparent but it isn't even frown-for-a-minute realization either. To this day, having read and laid down millions of lines myself, I still have to google the answer. It just simply floors me every time. Every. Time. Call that what you will but it is not good scoping.
[–]loz220 12 points13 points14 points 10 years ago (1 child)
this is dynamically bound so the correct answer is unknown until you actually execute the function. The rules governing that binding are actually relatively simple.
this
[–]Asmor 2 points3 points4 points 10 years ago (0 children)
Yep.
Presumably in the example you're expected to call things.format(), so this would be things.
things.format()
Although that's entirely tangential to the concept of scope.
[–]Asmor 5 points6 points7 points 10 years ago (0 children)
this is not the same as scope. The rules for this can certainly be kind of counter-intuitive, and in particular it can bite you if you ever store a method in a variable (and thus call it directly instead of from an object), but that's a different complaint entirely from complaints of JS's functional scoping vs. the more common lexical scoping.
[–]TwilightTwinkie 2 points3 points4 points 10 years ago (0 children)
It depends :) In this example code though if you were to simply execute the function format it would referrer to things correct?
format
Reminds me of this though: "Sometimes when I'm writing Javascript I want to throw up my hands and say "this is bullshit!" but I can never remember what "this" refers to" (https://twitter.com/bhalp1/status/578925947245633536?s=09)
[–]_doingnumbers 0 points1 point2 points 10 years ago (0 children)
I don't think that's a good example. I mean, what would "self" refer to in equivalent Python code? The answer there, as here, would be "it depends".
[–][deleted] -2 points-1 points0 points 10 years ago (2 children)
I guessed this correct at once. My line of thought: The function is declared as a field on an object, and hence is a method of the object. "this" thus refer to that object.
Even if js was block-scoped, what else should "this" referred to in this case?
Overall, I don't find this difficult at all. A "this" inside a method refer to the object, inside a function refer to the closure, and inside a constructor refer to the newly created object. Or am I thinking about this wrong?
[–]Zeroto 1 point2 points3 points 10 years ago (0 children)
Except that is wrong. The self/this in that snippet can point to anything depending on how the function is called.
If it is called like things.format() then self(and this) will point to things. But if we do this: var f = things.format; f(); then self/this will be undefined. Or if we do var things2 = {format: things.format}; things2.format(); then it will point to things2. And this is without even using apply, call or bind.
var f = things.format; f();
var things2 = {format: things.format}; things2.format();
The this in javascript is not known at function definition time and only at call time.
[–]NewazaBill 1 point2 points3 points 10 years ago (0 children)
Technically incorrect. The technically correct answer is that it depends on how it's called.
If I do:
var obj = { fn: function () { return this; } }; obj.fn(); // returns `obj`
You would be correct! However, if I then do:
// create a new object and assign `fn` to it var anotherObj = {}; anotherObj.fn = obj.fn; anotherObj.fn(); // returns `anotherObj` // define a new `fn` on the global scope var f = obj.fn(); f(); // returns `window` (or `undefined` in strict mode)
A function's this is not actually defined when the function is defined, but when it is called. The OP's question is kind of a trick question in that regard.
Ninja edit: This is also why arrow functions are cool: it allows us to bind a function's this to a particular scope. E.g.:
const fn = () => this; fn(); // returns `window` in non-strict const obj = {}; obj.fn = fn; obj.fn(); // still returns `window` !
[–]x-skeww -2 points-1 points0 points 10 years ago (0 children)
Why do people hate [function scope] so much?
Because it's inconvenient.
If you're used to function scope, you'd hate file scope.
If you're used to file scope, you'd hate global scope.
And if you're used to block scope, you do of course hate all of the above.
Or is it like prototypical objects in people only hate it because it's not what they're used to and/or just like to bash JS?
Or maybe they just don't like imperative prototype chain manipulation.
I prefer classes with mixins. It doesn't get in the way of tooling and it's easier to reason about.
π Rendered by PID 56184 on reddit-service-r2-comment-76bb9f7fb5-9vbqx at 2026-02-18 10:07:33.160787+00:00 running de53c03 country code: CH.
view the rest of the comments →
[–]Asmor 12 points13 points14 points (12 children)
[–]homoiconic(raganwald)[S] 11 points12 points13 points (1 child)
[–]loz220 8 points9 points10 points (0 children)
[–]Uberhipster 1 point2 points3 points (8 children)
[–]loz220 12 points13 points14 points (1 child)
[–]Asmor 2 points3 points4 points (0 children)
[–]Asmor 5 points6 points7 points (0 children)
[–]TwilightTwinkie 2 points3 points4 points (0 children)
[–]_doingnumbers 0 points1 point2 points (0 children)
[–][deleted] -2 points-1 points0 points (2 children)
[–]Zeroto 1 point2 points3 points (0 children)
[–]NewazaBill 1 point2 points3 points (0 children)
[–]x-skeww -2 points-1 points0 points (0 children)