I want to document the differences between classes and closures in JavaScript. Both class-based, object-oriented and functional JavaScript exist in the wild. For example in React, both class components and function components with hooks are supported.
I don't want to assert that you would ever choose one programming paradigm over another purely based on their performance, but is it possible that in modern JavaScript engines classes have a better chance to be optimized due to their language support?
I was under the impression that classes were just syntactic sugar for inheritance implemented with a prototype chain, but while this still appears to be a popular point of view, it is not correct.
In addition, their are new proposals such as decorators and private fields which continue to put more distance between classes and their alternatives. While decorators are just the composition of higher-order functions and private fields can be emulated, I expect that JavaScript engines may not perform identical optimization in all cases.
I am also aware that JavaScript engines employ techniques such as hidden classes to improve their performance. To my knowledge this optimization is not class specific. However, this made me curious...
Are their any optimizations that current JavaScript engines perform on classes, that are may not be applied in cases where classes are avoided? Would their be invariants that might be easier to identify and exploit due to the consistent nature of the class-based syntax?
I did try to read through the source code of the V8 engine, but it is large and complex, and I expect would take me a significant amount of time before I could even create a hypothesis. Therefore, I think this question is better left to someone with more experience than me in this domain.
So far my quest has led me from the parser to the abstract syntax tree and then to the bytecode generator used by the interpreter. I am aware that the interpreter (Ignition) is just the first stage of the JIT, and is followed by the compilers Sparkplug and Turbofan, which then transform the bytecode into machine code.
Indeed, classes do appear to have specific bytecode generation as seen in the BuildClassLiteral
in the BytecodeGenerator
class. However, I am unaware if this could yield better performance further into the pipeline of compilers.