Class properties in JS: a case study of WTF
I’m not the first one to point out that JS development is broken. It’s also not my first time around the JS rodeo. But sometimes, you see something so royally messed up that you can’t help but marvel.
I’ve used React in the past but I had never found a state management solution that I liked. So, I decided recently to try my hand at MobX, a popular library that a colleague of mine recommended.
So far, I really like what I see. Then I come across this:
import { observable } from 'mobx';class MyClass {
@observable myProp = 'lol';
}i = new MyClass();
i.myProp === 'lol' // true
The thing that MobX introduces is the @observable
decorator, which is a pretty cool thing that allows a data property to be continuously monitored for changes, which then cause dynamic updates in the DOM (and other things). The data property in this example is myProp
.
But my ES5/6/2015/7/2016/2017/next skills not being that advanced, I find myself confused. I’m confused because, as far as I know, you can’t declare data properties like myProp
inside of the class syntax, and even if you could, it would be bad practice since class syntax is just sugar for defining methods on a prototype, and you don’t normally define properties on prototypes. Nevertheless, MobX’s documentation says things like “The @observable can be used on instance fields and property getters” and “This can simply be done by annotating your class properties with the @observable decorator (ES.Next).” So what gives?
“Stick to the script, Ersin,” a voice on my left shoulder tells me. “Don’t ask too many questions. You’re on the edge of the woods now. Just stick to the path, baby, turn around and go back home. You don’t need to go to grandma’s house. You don’t need to fight any wolves. Just declare the properties.”
“But…ah…what if I just…surely just one quick search on MDN wouldn’t hurt…”
I will spare you the details of my exhaustive search. I will forgo mentioning how searching for “______ es6” is not enough, even if you know that the feature is in ES6, how you must duplicate searches with ES2015, or ES2016, or ES7 (which isn’t even a thing, but people use it anyway), or ES2017, or ES.next (which sounds like an Estonian foreign investment marketing campaign). I will avoid mentioning all of the irrelevant deep dives into class syntax and scoping that I had to wade through and just give you the fruits of my labor:
- Class data properties are not part of any official ES standard. The measure was put forward in a proposal for ES2015/ES6, debated and rejected. It was floated again for ES2016, and while I haven’t found any records of a debate or official decision, it’s definitely not in the language, meaning that it was rejected again.
- Babel has a plugin called transform-class-properties that transpiles the rejected data property syntax to allow to use this rejected feature.
- MobX, a mission-critical production-tested library used by thousands of projects worldwide, decided to rely on this Babel plugin that enables you to use a feature that isn’t part of any standard but rather was twice proposed to be part of the language and twice rejected. The library’s documentation states that its own
@observable
syntax is optional; it doesn’t mention anywhere that the language syntax it relies on is not obscure, not deprecated but literally rejected.
Does anyone else think this is insane? It’s already become standard operating practice for JS developers to use proposed features that haven’t yet found their way into Node or web browsers, which still rubs me the wrong way. But how many people who include transform-class-properties
in their .babelrc are aware that they’re relying on rejected syntaxes? I certainly had no idea.
Some people defend the insanity of JS development by saying that at least it’s democratic. Bazaar vs. cathedral, bazaar wins. But what’s democratic about big projects backed by large companies totally ignoring open standards, even if those projects are open source? It’s as if the JS ecosystem looked at common law, said “yeah a system based entirely on hundreds of years of precedents by authority figures seems like a good way to disseminate knowledge,” and then proceeded to shrink the timescale to the past four years or so.
Worse still, at least the class properties proposal is a reject from ES2016, which is the current latest and greatest. What happens when MobX maintains @observable
in 2017? 2018? With each passing year, the origins and real meaning of the language feature it relies upon will become increasingly obscure, unless one day the proposal is floated again and finally adopted.