简体   繁体   中英

is it possible to delcare an anonymous non-IIFE JavaScript function with a property

I have on one occasion found it useful to assign properties to functions before passing them as arguments to other functions.

That looked like this (sorry about any confusion between anonymous functions and variable-assigned function objects, I think they are not the same thing):

"(could strict mode have something to do with this?)"

var funcOne = function(arg1, arg2) { return arg1 + arg2; };
funcOne.process = true;
var funcTwo = function(arg1, arg2) { return arg1 + arg2; };
funcTwo.process = false;

var procFunc = function(argFunc) {
    if (argFunc.process) { 
        return argFunc(1,2);
    }
    return "not processed"
}

procFunc(funcOne); // 3
procFunc(funcTwo); // "not processed"

I would like to declare an anonymous function and simultaneously assign properties to it so when it is later called as part of a function array stack, conditional code can depend on the property.

Something like:

"(could strict mode have something to do with this?)"

var funcOne = function(arg1, arg2) { return arg1 + arg2; }.process = true;
var funcTwo = function(arg1, arg2) { return arg1 + arg2; }.process = false;

var procFunc = function(argFunc) {
    if (argFunc.process) { 
        return argFunc(1,2);
    }
    return "not processed"
}

procFunc(funcOne); // "not processed"
procFunc(funcTwo); // "not processed"

Where the unexpected "not processed" is because confusingly, JavaScript is actually assigning the value 'true' and 'false' to the funcOne and Two variables, and it does not throw an error when the conditional if (argFunc.process) is evaluated (regardless, as I suppose I expect, of "strict mode").

I have gotten this to work functionally anonymously using an IIFE that assigns the 'anonymous' function to a variable then assigns the property on that variable and returns that variable out of the IIFE, but I was hoping there was a JavaScript syntax for this or just a better way, maybe.

To my sensibility, the dot property assignment I tried does not make sense. What if programmer wanted to assign multiple properties to the anonymous function?

I had a short lived hope with var funcOne = function (arg1, arg2) { return arg1 + arg2; } = { process: true }; var funcOne = function (arg1, arg2) { return arg1 + arg2; } = { process: true }; but that throws a SyntaxError: Invalid left-hand side in assignment .

To create a function, you have two options:

  • Function declaration

With this, no expressions are involved:

function funcOne(...) {
}

There is no way to tack on something like funcOne.process = true except as a separate, standalone statement. (Not that that's a bad thing - I'd actually prefer such a second statement, it's probably the easiest to read)

  • Function expression

With this, you have a function expression you can assign to a variable name - but you can't assign to the variable name and assign a property to the function at the same time with = , because = (the assignment operator) resolves to the value that was assigned , regardless of what sort of thing is on the left-hand side of the = . This is why the following doesn't work:

var funcOne = function x(arg1, arg2) { return arg1 + arg2; }.process = true;

Above, the value that was assigned is true , so the value that funcOne receives is true (no reference to the function remains).

But, you can use Object.assign , which resolves to the first parameter, the object that was assigned to, to combine the declaration of the function and the additional property you want to assign to the function object in a single mostly-concise statement:

 var funcOne = Object.assign( (arg1, arg2) => { return arg1 + arg2; }, { process: true } ); console.log(funcOne(3, 4));

functional composition is the right tract... here is a function for adding a prop to a different function.

var addProp = function(fun, propName, propVal){fun[propName] = propVal; return fun}


var funcOne = addProp(function(arg1,arg2){ return arg1 + arg2; }, "process",true);
var funcTwo = addProp(function(arg1,arg2){ return arg1 + arg2; }, "process",false);

the resulting code looks like that. and behaves as expected

Another way of doing this would be with a helper function:

const addProp = (fn, value) => { fn.process = value; return fn; };

const myFunc = addProp((arg1, arg2) => arg1 + arg2, true);

console.log(myFunc.process); // => true
console.log(myFunc(1, 2));   // => 3

You could probably also do this with a decorator, although that's a proposal for future versions of ECMASCript and would require transpilation to work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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