Live data from Hacker News

On JavaScript's Weirdness

stack-auth.com

71–80 of 85 posts

Re: On JavaScript's Weirdness

#71

Earlier quoted context omitted.

No, that's a mistake in the article. The variable is still captured by reference, but `let` is causing it to be re-declared on every iteration of the loop, not mutated. The following code prints 1, 2, 3. It wouldn't do that if the variable was captured by value. for (let i = 0; i console.log(i)); i++; }

The behavior of "let" with for loops where the variable is declared more times than it is initialized, despite the source code having one declaration that is also the only initialization, is not very explicit.

Fair, but that's a property of for loops. Variable in closures are still always captured by reference.

Re: On JavaScript's Weirdness

#72
post #43

I remember properly learning JS from “The Good Parts” book, which makes it known from the start that JS is a nasty language but if you ignore many sharp edges it can be nice and elegant. I think this is especially true with (a subset of) TS. All you need is a very, very strict linter, and then you get to pretend you’re working in a mostly solid language.

I didn't read JS The Good Parts until it was well outdated, and I was glad to see that a lot of the sharp edges that Crockford lists have largely been eliminated. The book was written circa ES3, so some problematic features were removed in strict mode, we have replacements for some (let/const, for-of loops, etc), and we can sweep prototypes under the rug with ES6 classes, sometimes arrow functions even avoid awkward this-binding issues. The rest, like you said, TypeScript + a linter takes care of.

Re: On JavaScript's Weirdness

#73
post #63

Earlier quoted context omitted.

Yes, it's about block scoping — but that doesn't make it less weird . In most languages this doesn't really make sense — a variable is a piece of memory, and a reference refers to it. JavaScript doesn't work like that, and that's weird to many. What's the mistake that I made there? I just didn't explain why it happens. I briefly mentioned this in the later paragraphs — it makes sense to some people, but not to most.

OK so for one the title of that section is off: > JS loops pretend their variables are captured by value This has to do with how for loops work with iterators, but also what `let` means in variable declaration. You talk about 'unrolling a for loop' but what you're doing is 'attempting to express the same loop with while'. Unrolling would look like this; // original: for (let i = 0; i console.log(i)) } // unrolled: {…

I mentioned that the title makes no sense in the sentence right after it:

> Yes, the title makes no sense, but you'll see what I mean in just a second.

And yes, I didn't explain the exact mechanics of the ES spec which make it happen — but I would argue that "variables can be modified until they're out-of-scope" is even more unintuitive than just remembering this edge case. And I'm not trying to be an ECMAScript lawyer with the post, rather I'd just show a bunch of "probably unexpected" behaviors of JavaScript.

Re: On JavaScript's Weirdness

#75

I'd like to understand why `document.all` is slower than `getElementById`. Couldn't any even somewhat decent optimizing compiler trivially compile the first to the latter? Like, I don't mean in weird cases like `const all = document.all; return all[v]`, or iterating over it, just the general one where someone directly does `document.all.foo` or `document.all[v]`, ie the 99.99% case. When faced with the choice to comp…

This was like 2004. Chrome, Safari, and Firefox all had getElementById in their first versions in like 2003, Opera had it in version 7, Internet Explorer was the odd one out.

This was IE6 days, the real bad old days. Remember that we were still mostly constrained to XMLHTTPRequests for calls to APIs

Anything actually important to be done in a web browser didn't use javascript, it used an ActiveX Component/extension, a java applet, or Flash or Shockwave (by Macromedia at the time!)

Re: On JavaScript's Weirdness

#77
Variable declared outside the loop construct lives outside the loop.

Variable declared inside the loop construct lives inside the loop.

Seems intuitive to me.

The complex thing here (and what seems to have confused the author) is the distinction between when the reference to the variable is captured vs. when the setTimeout() callback occurs.

Actually, this article shows what good shape Javascript is in. As it says, commonly deployed linters catch the really bad stuff, effectively deprecating those things.

Pretty much the rest of it to do with specific domains outside of javascript, like what actually is a character and IEEE floating point, or are rather out-of-the-way things like document.all and sparse arrays (not that people don't use sparse arrays, but it's entirely optional and if you're going to voluntarily go into that cave, I guess you must be happy to tangle with the bears living there.)

Re: On JavaScript's Weirdness

#78

What I don't understand is why, after twenty years, we still haven't versioned Javascript. A simple: 'v2'; At the top of every file could let us eliminate all this 20-year old cruft (like document.all hacks to support Internet Explorer). Yet, despite the already established `use strict`; (which is basically 'v1.5'), the community seems completely against modernizing the language.

[deleted]

Re: On JavaScript's Weirdness

#79
These weird cases are not because JavaScript is bad, but because it has to be backwards compatible. So where other languages can just delete old quirks from the language, JavaScript has to keep them in.

Re: On JavaScript's Weirdness

#80
post #18

I can pretty confidently say that every article I have seen in the past 5 years that complain about weirdness of JavaScript is about things that you would never do in a modern, production-level codebase. Many of these issues are about pre-ES6, outdated practice (e.g. eval, using == operator) that are almost certainly going to be flagged by a linter. Very occasionally, you do get hit by some weirdness, but likely does…

If the language needs a linter to keep otherwise-competent developers from introducing potentially maddening bugs into the codebase, it's weird. JS was developed in a hurry and has been extended into doing things it was never meant to do, and it shows.

> If the language needs a linter to keep otherwise-competent developers from introducing potentially maddening bugs into the codebase, it's weird.

This is an odd way to phrase things. A better way to look at this is that there are programming tasks which can be easily automated and tasks which cannot be easily automated. The ones which can be easily automated should be, so that humans can focus on the ones which cannot be easily automated. Do you not run automated tests, since those same tests could be done over and over by hand?

Post reply on HN