Proxy
If you are against using __proto__ or anything related to it, but still want to inherit, you can use "Proxies" .
var ObjectCallable_handler = { get: function get(self, key) { if (self.hasOwnProperty(key)) { return self[key]; } else { return self.__inherit__[key]; } }, apply: function apply(self, thisValue, args) { return (self.__call__ || self.__inherit__.__call__).apply(self, args); } }; function ObjectCallable(cls) { var p = new Proxy(function() { }, ObjectCallable_handler); p.__inherit__ = cls; return p; }
Pros
- Supports inheritance.
- Does not include a traditional prototype chain.
- ES6 project .
Vs
setPrototypeOf
If there is no support for Proxies, you can try setPrototypeOf polyfill.
Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) { obj.__proto__ = proto; return obj; } function ObjectCallable(cls) { var f = function() { return f.__call__.apply(f, arguments); }; Object.setPrototypeOf(f, cls); return f; }
Pros
- Most likely, we will work best now and in the future.
- ES6 project .
Vs
- Uses custom
__proto__ via polyfill and requires testing through the engines / browsers you want to support. setPrototypeOf not currently implemented in any browser.
Copy
This is the simplest solution with the least amount of functionality, but it guarantees work from almost anywhere. Create a new function and clone object properties onto it.
function ObjectCallable(cls) { var f = function() { return f.__call__.apply(f, arguments); }, k; for (k in cls) { f[k] = cls[k]; } return f; }
Pros
- It works almost everywhere.
Vs
- Does not support any semblance of inheritance or prototype structure.
Conclusion
What you want to do with replicating Python __call__ functionality in JavaScript will take more time, because ES6 is developed and implemented in most engines or relies on non-standard functions like __proto__ .
source share