Private class fields in JavaScript are a runtime minefield

My post-mortem from yesterday’s Site.js bug that was preventing Let’s Encrypt certificate renewals checks from running.

· · Web · 4 · 2 · 3

Actually, scratch that, the issue here isn’t private class fields at all but passing a reference to a method (the use of private class fields, if anything, causes an error while without them it fails silently). Writing up a revision now :)

This is now updated and the blame placed where it is deserved (and private class fields deserve an apology) :)

@aral Easier way:
()=>{ this.whatever(); }
Which is a closure, and "this" is captured from the scope you declared that in.

@mdhughes Not sure if it communicates intent as clearly as bind() though, as it’s explicit about its purpose.

@aral Other way I think. bind is an ugly old hack to set a property of a function object. => is just a nice Scheme lambda that wandered into a bad neighborhood.

@mdhughes @aral using an anonymous function just because you want to use the side-effect of capturing the lexical scope is also a hack. They're both fine, but .bind() clearly states explicit intent.

@0xadada @aral It's not a "hack", that is the purpose of a lambda in real functional languages; JS is sometimes called Scheme-like but it's only lately got all the tools for that to be true. In a real Scheme, you build "objects" by capturing scope and returning a lambda that parses messages.

@mdhughes @aral I agree, in real functional languages, yes. But JS is not that

@0xadada @aral @mdhughes The `bind()` may or may not be clearer for some given person reading the code, but I don't think it's correct to say that the main purpose of a lambda is an obscure side-effect of it.

The arrow function is designed intentionally different from the classical JS `function()` and that intention is to make `this` less confusing. The arrow function and the `let` and `const` forms make JS a better functional language that is easier to reason about, and that's what they're for.
@aral @mdhughes @0xadada JavaScript is a language with higher-order functions, closures and affordances for writing functional code. It also has prototype-oriented aspects and class-oriented aspects.

React is a functional reactive programming framework, or at least strives to be and is inspired by the concept.

@clacke @aral @mdhughes I didn't say the purpose of a function is for the lexical scope, but in his example, he uses the lambda specifically for it's scope. Arguably the same thing as doing bind(), but by invoking another call onto the stack

@0xadada @aral @mdhughes No, I'm saying the purpose of an arrow function is to create a closure, and you're saying creating a closure and capturing the variables of the environment is a side-effect and a hack.

I think creating the closure like in any normal language is neater than using this obscure method-rebinding functionality that JS has.

@aral yeah, felt that one once to often 😅
Now `this` is my anti-keyword in JavaScript, whenever I see it, it try to refactor around it.

@aral Some people put rebindings in all their constructors as a preventive measure from surprises:

this.method = this.method.bind(this) this.otherMethod = this.otherMethod.bind(this)

In fact, React.createClass() that React people used before ES6 does this under the hood automatically, so I guess that's why the habit has carried over to class syntax, so that method code can look like it always has and can just attach this.method to event handlers and such.
Sign in to participate in the conversation
Aral’s Mastodon

The social network of the future: No ads, no corporate surveillance, ethical design, and decentralization! Own your data with Mastodon!