Python __call__ replication in javascript?

I want to replicate an instance of a class without using the module template.

Here is my best attempt. However, it uses __proto__ , which I'm not sure about. Can this be done without __proto__ ?

 function classcallable(cls) { /* * Replicate the __call__ magic method of python and let class instances * be callable. */ var new_cls = function () { var obj = Object.create(cls.prototype); // create callable // we use func.__call__ because call might be defined in // init which hasn't been called yet. var func = function () { return func.__call__.apply(func, arguments); }; func.__proto__ = obj; // apply init late so it is bound to func and not cls cls.apply(func, arguments); return func; } new_cls.prototype = cls.prototype; return new_cls } 
+6
source share
1 answer

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__ .

+4
source

Source: https://habr.com/ru/post/950302/


All Articles