Function() 构造函数

Baseline 已广泛支持

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2015 年 7 月⁩以来,各浏览器均已提供此特性。

Function() 构造函数创建 Function 对象。直接调用构造函数可以动态创建函数,但这会带来与 eval() 相似的安全和性能问题(尽管后者影响更大)。然而,与 eval 不同(它可能可以访问局部作用域),Function 构造函数创建的函数仅在全局作用域中执行。

试一试

const sum = new Function("a", "b", "return a + b");

console.log(sum(2, 6));
// Expected output: 8

语法

js
new Function(functionBody)
new Function(arg1, functionBody)
new Function(arg1, arg2, functionBody)
new Function(arg1, arg2, /* …, */ argN, functionBody)

Function(functionBody)
Function(arg1, functionBody)
Function(arg1, arg2, functionBody)
Function(arg1, arg2, /* …, */ argN, functionBody)

注意: Function() 可以使用或不使用 new 调用。两者都创建一个新的 Function 实例。

参数

arg1, …, argN 可选

将用作函数形式参数名称的名称。每个参数都必须是一个字符串,对应一个有效的 JavaScript 参数(可以是普通 标识符rest 参数解构 参数,可选带 默认值),或者是一系列用逗号分隔的此类字符串。

由于参数的解析方式与函数表达式相同,因此可以接受空格和注释。例如:"x", "theValue = 42", "[a, b] /* numbers */" — 或 "x, theValue = 42, [a, b] /* numbers */"。("x, theValue = 42", "[a, b]" 也是正确的,但非常令人困惑。)

functionBody

一个包含构成函数定义的 JavaScript 语句的字符串。

描述

使用 Function 构造函数创建的 Function 对象在函数创建时进行解析。这不如创建 函数表达式函数声明 并在代码中调用它们那样高效,因为后者的函数会随同其他代码一起解析。

传递给函数的除最后一个参数外的所有参数,都被视为要创建的函数中参数的标识符名称,并按传递的顺序排列。该函数将被动态编译为函数表达式,其源代码的组装方式如下:

js
`function anonymous(${args.join(",")}
) {
${functionBody}
}`;

通过调用函数的 toString() 方法可以看到这一点。

但是,与普通的 函数表达式 不同,名称 anonymous 不会添加到 functionBody 的作用域中,因为 functionBody 只能访问全局作用域。如果 functionBody 不处于 严格模式 下(主体本身需要带有 "use strict" 指令,因为它不会从上下文继承严格性),您可以使用 arguments.callee 来引用函数本身。或者,您可以将递归部分定义为内部函数

js
const recursiveFn = new Function(
  "count",
  `
(function recursiveFn(count) {
  if (count < 0) {
    return;
  }
  console.log(count);
  recursiveFn(count - 1);
})(count);
`,
);

请注意,组装源代码的两个动态部分 — 参数列表 args.join(",")functionBody — 将首先被单独解析,以确保它们都语法有效。这可以防止类似注入的尝试。

js
new Function("/*", "*/) {");
// SyntaxError: Unexpected end of arg string
// Doesn't become "function anonymous(/*) {*/) {}"

示例

使用 Function 构造函数指定参数

以下代码创建一个接受两个参数的 Function 对象。

js
// Example can be run directly in your JavaScript console

// Create a function that takes two arguments, and returns the sum of those arguments
const adder = new Function("a", "b", "return a + b");

// Call the function
adder(2, 6);
// 8

参数 ab 是在函数体 return a + b 中使用的形式参数名称。

从函数声明或函数表达式创建函数对象

js
// The function constructor can take in multiple statements separated by a semicolon. Function expressions require a return statement with the function's name

// Observe that new Function is called. This is so we can call the function we created directly afterwards
const sumOfArray = new Function(
  "const sumArray = (arr) => arr.reduce((previousValue, currentValue) => previousValue + currentValue); return sumArray",
)();

// call the function
sumOfArray([1, 2, 3, 4]);
// 10

// If you don't call new Function at the point of creation, you can use the Function.call() method to call it
const findLargestNumber = new Function(
  "function findLargestNumber (arr) { return Math.max(...arr) }; return findLargestNumber",
);

// call the function
findLargestNumber.call({}).call({}, [2, 4, 1, 8, 5]);
// 8

// Function declarations do not require a return statement
const sayHello = new Function(
  "return function (name) { return `Hello, ${name}` }",
)();

// call the function
sayHello("world");
// Hello, world

规范

规范
ECMAScript® 2026 语言规范
# sec-function-constructor

浏览器兼容性

另见