繁体   English   中英

JavaScript类有一个等同于Python类__call__的方法吗?

[英]Do JavaScript classes have a method equivalent to Python classes' __call__?

在Python中,您可以为类实现__call__() ,以便调用类本身的实例来执行__call__()方法。

class Example:
    def __call__(self):
        print("the __call__ method")

e = Example()
e() # "the __call__ method" 

JavaScript类有一个等效的方法吗?

编辑

结合讨论的摘要答案:

  • Python和JavaScript对象与真正的等价物不够相似(原型与基于类, self ,与this相比)
  • 该API 可以使用但是可以实现代理 ,也许使用-或修改原型bind
  • 通常不应该这样做:它远离JS的结构和JavaScript的正常使用,可能会在其他JS开发者,你的未来自我之间产生混淆,并可能导致特殊的副作用。

执行此操作的唯一方法是构造函数显式返回可以调用的函数。 (在Javascript中,如果没有在构造函数中显式return ,则会return新创建的实例 - 但是这样的实例将是普通对象,而不是函数。)

 class Example { constructor() { return function() { console.log('function running'); } } } const e = new Example(); e(); 

但这样做真的很奇怪 ,并且不允许你引用原型上的任何属性,或类似的东西。 最好避免它,或者创建一个返回函数的普通函数:

 const example = () => () => console.log('function running'); const e = example(); e(); 

我基本同意@CertainPerformace,这不是你在普通的JS代码中会做的事情。 话虽如此,代理提供了很多可能性,你可以创建一些令人惊讶的接近(表面上)Python的__call__()

例如:

 class F extends Function{ constructor(someID, arr, n){ super() this.id = someID this.arr = arr this.n = n return new Proxy(this, { apply(target, thisArg, argumentsList) { return target.__call__(...argumentsList); } }) } __call__(a){ // simple mult functions return a * this.n } *[Symbol.iterator](){ // make it iterable for demo purposes yield *this.arr.map(this) // call itself in a map! } } let f = new F("FrankenFunction", [1, 2, 3, 4], 5) // access instance variable console.log("id:", f.id) // call it console.log("calling with 100: ", f(100)) // use the iterator // get multiples of calling this on arr console.log([...f]) // change the __call__ function to power instead F.prototype.__call__ = function(a){ return a ** this.n } // change n to get squares: fn = 2 // call it again with new __call__ console.log("calling with 10:", f(10)) // 10**2 console.log([...f]) // or iterate 

我真的不确定这是否是一个好主意,但这是一个有趣的实验。

你可以完成这件事,但是以一种相当奇怪的方式。

JavaScript中没有像__call__()__add__()__sub__()的东西--JavaScript不支持运算符重载。

但是,如果您真的想让对象可调用,可以通过为函数提供不同的原型来实现:

 function createCallableObject(cls, fn) { // wrap the original function to avoid modifying it const wrapper = (...args) => fn(...args) // set the prototype of the wrapped function so we can call class methods Object.setPrototypeOf(wrapper, cls.prototype) return wrapper } class Example { method() { console.log('This is an instance of class Example') } } function example() { console.log('This is a function') } const obj = createCallableObject(Example, example) obj() // 'This is a function' obj.method() // 'This is an instance of class Example' console.log(obj.constructor) // 'class Example { ... }' 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM