user2363207
user2363207

Reputation:

How does Function class works?

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

Answers (3)

Ajeet Shah
Ajeet Shah

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:

  1. It is slow as it uses function eval() to evaluate the strings
  2. It is harder to debug lines within such function
  3. eval() can execute any javascript code, hence opens the vulnerabilities

Upvotes: 0

elixenide
elixenide

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 new Function object. In JavaScript every function is actually a Function 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 the new operator) has the same effect as invoking it as a constructor.

Upvotes: 3

choz
choz

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

Related Questions