Reputation:
I was reading through the Airbnb JavaScript Style Guide and I came across this section that mentions the following function:
var subtract = Function('a', 'b', 'return a - b');
I tested this in the Chrome debugger console by entering the line above and then entering:
subtract(7,3)
and it returned 4
. I was very surprised that it actually worked.
The style guide mentioned that it is not a good idea to do this, but it got me to thinking about this function syntax. I've never seen a function that has no body return a proper result.
How/why does this work, how long has it been around, and what are the guidelines/best practices for using it?
Upvotes: 4
Views: 101
Reputation: 19823
Constructor function
var subtract = Function('a', 'b', 'return a - b');
or
var subtract = new Function('a', 'b', 'return a - b');
var result = subtract(10, 5); // result : 5
This is defining a Javascript function with a built-in JavaScript function constructor called Function()
. This is same in result as defining anonymous function using expression:
Anonymous function using expression:
var subtract = function(a, b) { return a - b); }
var result = subtract(10, 5); // result : 5
Constructor function syntax:
new Function ([arg1[, arg2[, ...argN]],] functionBody)
All arguments (strings) are optional with a required functionBody
(string). It uses eval()
function to evaluate strings. It returns a new function object which is used to call the function.
Functions with constructor should be avoided as:
eval()
to evaluate the stringseval()
can execute any javascript code, hence opens the vulnerabilitiesUpvotes: 0
Reputation: 44831
This creates a function using the Function
object instead of the "normal" function
syntax. Notice the capital "F".
var subtract = Function('a', 'b', 'return a - b');
Means that you define a function with parameters a
and b
, with body return a - b
. It's equivalent to
var subtract = function (a, b) { return a - b; };
Typically, you want to use new
when invoking a constructor like this, but it works just as well without it; it's just a little harder to read (for humans).
From the Mozilla Developer Network explanation:
The
Function
constructor creates a newFunction
object. In JavaScript every function is actually aFunction
object.Syntax
new Function ([arg1[, arg2[, ...argN]],] functionBody)
Parameters
arg1
,arg2
, ...argN
Names to be used by the function as formal argument names. Each must be a string that corresponds to a valid JavaScript identifier or a list of such strings separated with a comma; for example "x", "theValue", or "a,b".
functionBody
A string containing the JavaScript statements comprising the function definition....
Invoking the
Function
constructor as a function (without using thenew
operator) has the same effect as invoking it as a constructor.
Upvotes: 3
Reputation: 17868
Taken from MDN.
The Function constructor creates a new Function object. In JavaScript every function is actually a Function object.
In your sample,
var subtract = Function('a', 'b', 'return a - b');
a
and b
are arguments that will be passed to the function body, which is return a - b
.
The last parameter will always be the function body
So if you pass it like,
var subtract = Function('a', 'b');
// Reference error b is not defined
This sample actually equals to,
var subtract = Function('a, b', 'return a - b');
Or in other version,
var subtract = function(a, b) { return a - b; };
or
var subtract = (a, b) => a - b;
Upvotes: 2