I'm not dissing it, that's great it does this. But I'm a bit surprised (and happy!) that this is all it does.
I'm not dissing it, that's great it does this. But I'm a bit surprised (and happy!) that this is all it does.
- no more messing with .constructor, .prototype
- calling parent object is super() easy :)
- you can have static methods
- no need to even type function for methods
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
For someone that has learned JS as his/her first programming language, the new syntax is the one that feels confusing.
I do agree that it is easier to understand the new syntax if you have experience with a language that use the same syntax. However, that's not learning anything new. It's simply using concepts that you already know.
Look at all the complaining about Lisp and Rust syntax which boils down to "ugh, this is unfamiliar."
But to answer your question, I think they are both within a pebble toss distance of each other. But still much harder than other languages due to `this`. `class` just unifies some patterns people were doing like inheritance.
In the past I've eventually resorted to copy and paste the same template every time I wanted to use inheritance with prototypes. With classes, I never have to think about these problems anymore. There is one way to define a class, and it always works like I expect it to.
IMO create a class in Javascript and adding a static method is the opposite of simplify things.
The simple way of doing it would be create a function in a module.
For me the use of static methods in languages like Java is a workaround. But it Javascript that workarount is not necessary.
>no need to even type function for methods
However, to be fair, you can do this with object method shorthand now:
const deepThought = {
theAnswer: 42,
tellTheAnswer() {
return `The answer to life, the universe, and everything is ${this.theAnswer}`;
},
};
deepThought.tellTheAnswer(); // => 'The answer to life, the universe, and everything is 42.'
Which is also quite elegant. I think they both have their places depending on the program. I think it depends on readability needs at the time, and whether an instance is better than just a container in that circumstance. var Foo = function () {};
Foo.prototype = {
bar() { return 'bar'; }
};
var f = new Foo();
f.constructor === Object;
When you use `class` you are still messing with `.prototype`. The danger is that programmers new to JS don't understand that they are and don't understand why that matters.Calling `super` is very anti-pattern in JS. Unlike classic OOP, parents are not static. Lots of very common things can rip that rug out from under you by modifying the parent in many different ways (createProperty, Symbols, proxies/reflection, etc).
Static methods do indeed exist without classes.
class Foo {
static bar() { return 'bar'; }
}
//is identical to
function Foo() {}
Foo.bar = function() { return 'bar'; }
If you use `Object.create()` and ES6 object literal syntax you don't have to type `function` either. You get the added bonus of being easily able to wrap it in a normal function that avoids constructor weirdness var someProto = {
bar() { return 'bar'; }
}
var myInst = Object.create(someProto); Foo.prototype.constructor = Foo;
...after replacing the prototype object that way. MDN (for example) covers this in a few pages, including:https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Ob...
That said, it's a pretty common bug, particularly with stuff like:
Foo.prototype = Object.create(FooParent.prototype) // Crockford-style inheritance
console.log(Foo.prototype.constructor.name) // "FooParent" function Cat() {
if (!(this instanceof Cat)) {
throw new Error("please use new!");
}
}
or, if you want to be a bit nicer to your users: function Cat() {
if (!(this instanceof Cat)) {
return new Cat();
}
} function CatDog () {
Cat.apply(this, arguments);
}
CatDog.prototype = Object.assign(Dog.prototype, Cat.prototype);
In the above example, CatDog is not an instance of Cat, since it never actually inherits from the Cat prototype.On .bind(this), that's exactly what I meant by keeping the old system. "Fixing" that magically would have required underlying changes. That said, since you brought up class fields and bind in the same post, there's always:
class Dog {
bark() { console.log('Bark!'); }
eat = (food) => console.log('Munch');
}
feedDog(dog.eat);