Blueprints – How objects work in JavaScript
innoq.com
innoq.com
obj[dynamic_property] = /* … */;
… for which you must, rather unfortunately, be aware of prototypes.(And if you can use Map, you probably should… it avoids the JS footgun here.)
In mid-late-2000s when the first idea of adding classes to the syntax came up, even Microsoft eventually said: nah, it's a bad idea. It's grafting incompatible concepts onto a language that doesn't need them.
And then Google in their "wisdom" went and forced classes onto the language. Take a guess why you need this for methods to work the way you expect them:
class Logger {
constructor () {
this.method = this.method.bind(this);
}
method (some, params) {
this.do_stuff()
}
/// ...
}`this`, of course, is a whole other bag of worms :(
You do indeed need to understand prototypes to explain this behavior. "Free functions" doesn't really make sense, because it obviates the need for classes.
It is, because classes are a thin wrapper over prototypes, but the whole "classic C++-like" class shenanigans translate very poorly to Javascript. And yet, with maddening bravery browsers have spent 10 years trying to make them work in some capacity (and don't get me started on the whole private members thing, or the autobind proposals, or...)
class Logger {
method = (some, params) => {
this.do_stuff()
}
/// ...
}
But your overall point stands.This is not Google's fault. It is the fault of Java developers. They expect everything to work like Java. They expect to find Java APIs everywhere.
I have never written classes like that. In fact, if I were to see a method being used in the way you are insinuating I would believe to have found a bug.
I strongly dislike class-based object orientation in general. But I'm glad we do not have to deal with dozens of ways to do OOP in JavaScript anymore.
It quite literally is. In there desire to push web components they also pushed quite a few (often questionable) solutions. See 17:59 here: https://youtu.be/y-8Lmg5Gobw
> But I'm glad we do not have to deal with dozens of ways to do OOP in JavaScript anymore.
There never were "dozens of ways". There always was only one: prototype based. And now there's this weird contraption on top that pretends its classes from C++-like languages (C++, Java, C# etc.) but is not.
its pitfalls should be understood and avoided instead of being afraid of JS prototypes
I feel like the people who are in that situation know who they are. The rest of the world benefits from knowing what subset of the ecosystem they want to work with, as opposed to "you should know everything", which is the most inclusive and the least useful statement.
Bit of a shame that the javascript guys didn't look at CLOS it might have been quite easy to port across. They do seem to share some implementation details (like the way which function is the right one to run).
"This is because a property declared in Rect.prototype is not available in Rect itself but only in objects created with new Rect. In this sense, Rect.prototype serves as a kind of “template” for objects produced by new Rect. As you can see, we are dealing with two different but quite similar concepts."
Ohhhh...Kaaaaay.
One tip I've learned when I have to use Javascript: Avoid 'this' whenever possible. There are 14 things 'this' can mean in Javascript, and whichever one it does mean depends on both the static context and the dynamic context (and possibly the phase of the moon). In most cases it's possible to avoid using 'this' by adding explicit variables. But I'm not sure it's always possible to avoid it. Yikes.
Oh, and I'm never quite sure when it's a good idea to use 'new'. TFA addresses 'new' a little bit. At least it's not as big a can of worms as 'this'.
This isn't really any different to other languages. The equivalent for Java would be "(non-static) properties are not available directly on the class but only on instances of that class"
> One tip I've learned when I have to use Javascript: Avoid 'this' whenever possible.
Arrow functions help a lot with this. Their 'this' cannot be overriden and thus is determined by static context only. With regular functions, the rule is that it depends how their called:
- If you call "foo.bar()" then "this" will be "foo".
- But if you do "var baz = foo.bar" then call "baz()", then "this" will be undefined.
- You can always set "this" explicitly by call a function with `.call`. In either "foo.bar.call(quz)" or "baz.call(qux)", "this" will be "qux".
> Oh, and I'm never quite sure when it's a good idea to use 'new'. TFA addresses 'new' a little bit. At least it's not as big a can of worms as 'this'.
Use "new" if and only if you're instantiating a class (whether that's written with the new class syntax or the older prototype syntax). That's it. It's possible to make a constructor work without "new", but it's an extra line of code and is generally considered non-idiomatic.