简体   繁体   English

Javascript:如何创建既像对象又像函数的变量?

[英]Javascript: How to create a variable that acts like both an object and a function?

In Javascript, I would like to create a variable (primitive or object) that can also be invoked as a function. 在Javascript中,我想创建一个也可以作为函数调用的变量(原始或对象)。

The desired result is: 理想的结果是:

console.log(myVar) // Outputs some variable previously defined
console.log(myVar()) // Outputs the result of some previously defined function

I would like the variable used to be exactly the same. 我希望变量过去完全一样。 For example, I do not want: 例如,我不要:

const myVar = () => 1;
myVar.prop = 2;

I have tried overriding both the Object.prototype.toString and Object.prototype.valueOf functions, but each need to be manually invoked: 我尝试覆盖Object.prototype.toString和Object.prototype.valueOf函数,但是每个函数都需要手动调用:

const myVar = () => 1;
myVar.toString = () => 2;
console.log(myVar + myVar) // This outputs 4, thanks to coercion
console.log(typeof myVar) // Outputs function, want 'number' in this example

My use case for this is the following scenario, where the result of someFunction(payload) acts as both a value and a function. 我的用例是以下情况,其中someFunction(payload)的结果既充当值又充当函数。

someFunction(payload)(options) // Result depends upon payload and options, returns a value
someFunction(payload) // Options is not specified, returns a value
someFunction(payload, options) // Would prefer not to use this method

In the desired use case, I'd like someFunction(payload) to act as an alias for someFunction(payload)() . 在所需的用例中,我希望someFunction(payload)充当someFunction(payload)()的别名。 I tried: 我试过了:

const someFunction = payload => {
    const innerFunction = options => {
        // Return value depending on payload and, if it exists, options
    };
    innerFunction.toString = () => innerFunction();
    return innerFunction;
};
console.log(someFunction(payload)(options)) // A value, correct
console.log(someFunction(payload)) // A function, do not want

I also tried using a combination of calling toString and eval (to executed the stringified function) to trigger the toString() , but could not get it to work. 我还尝试使用调用toStringeval的组合(以执行字符串化函数)来触发toString() ,但无法使其正常工作。

So I'm not entirely sure I understand the "why" of this question, but I am going to give this a shot. 所以我不能完全确定我理解这个问题的“原因”,但是我将对此进行一下介绍。

What you could do is create a data type and have it return a default value and then when you use the "new" constructor you could then get access to its values like the function. 您可以做的是创建一个数据类型,并使其返回默认值,然后在使用“新”构造函数时,您可以像使用函数一样访问其值。

So if you see in the below image I created a function and have values that could be used if I constructed the data type, however if I am just invoking the function I am able to return a value instead. 因此,如果您在下图中看到我创建了一个函数,并具有在构造数据类型时可以使用的值,但是,如果我只是调用该函数,则可以返回一个值。

If you use the constructor of the function and create a instance of this data type you can then just manipulate the value directly. 如果使用函数的构造函数并创建此数据类型的实例,则可以直接操作该值。

I dont think that totally gets you to where you want, but I am hoping it gets you a little closer. 我认为这不会完全将您带到您想要的地方,但是我希望它可以使您更近一些。

  function Payload(val, options) { this.innerFunction = () => { console.log(options)} this.value = val return val } console.log(Payload(10, {key:"KEY" })) // print 10 console.log(typeof Payload(10, {key:"KEY" })) // number x = new Payload(10, {key:"KEY" }) x.innerFunction() // returns {key:"KEY" } x.val // returns 10 

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

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