The article to me unveils following, either the author is confusing definition and behavior of each, a function, an object, and prototype, or the author is not good at all in explaining things.
How does this harsh judgment come about?
The article continuously suggests it was possible to create a callable object, starting with a plain object and making it callable, while in contrast everything boils down to providing/setting an object as a function-object's prototype. Thus, one never enables an object of being callable but one from the very beginning always deals with a function (callable in many ways by design) which, in regards to the article's example code, gets enhanced via its prototype.
And the biggest mistake of the example code is the introduction of an entirely unnecessary function which on top comes with the most misleading name ... createHybridObject.
What one is really dealing with gets obvious when the author’s example code is shortened to something like that ...
function invoke () {
console.log('invoked');
}
Object.setPrototypeOf(invoke, {
start: () => ({}),
stop: () => ({}),
currentGear: 0,
});
invoke();
The invoke function of the above example code is equal to Car of the authors article, after having it there re-assigned via …
Car = createHybridObject(Car, invoke);
There is no hybrid object … just do a simple logging of Car; there is always exclusively the original invoke function’s reference. Thus, one always deals with a function, and a function is an object too; it’s unique in a way that it carries / features an internal [[Call]] and/or [[Construct]] slot.
After having clarified that, the author’s entire approach is at stake.
Why, for instance, should currentGear be a prototype reference and not an own property of invoke. Since one is dealing with a function-object anyhow, why would one want to entirely replace the function’s prototype and not, for instance, just augment it? The next provided example code covers the same functionality like the author’s one, whereas the implemented approach is very expressive / straightforward about how it achieves / allows more freedom in the function-object’s extended model (properties / methods) design.
function callableCar() {
console.log('invoked');
}
const carOwnProperties = {
currentGear: 0,
};
const carMethods = {
start: () => ({}),
stop: () => ({}),
};
Object.assign(callableCar, carOwnProperties);
Object.assign(callableCar.prototype, carMethods);
console.log({ callableCar });
callableCar();