Get to know MDN better
此页面由社区从英文翻译而来。了解更多并加入 MDN Web Docs 社区。
警告:传递给此构造函数的参数会被动态解析并作为 JavaScript 执行。此类 API 被称为注入陷阱,是跨站脚本攻击(XSS)的潜在载体。
你可以通过始终传递 TrustedScript 对象而不是字符串,并强制使用受信任类型来降低此风险。
详见安全考虑章节。
Function() 构造函数用于创建 Function 对象。直接调用构造函数可以动态创建函数,但会存在安全问题以及与 eval() 类似(但远不那么严重的)的性能问题。不过,与可能访问本地作用域的 eval 不同,Function 构造函数创建的函数仅能在全局作用域中执行。
备注:调用 Function() 时可以使用或不使用 new。两者都会创建一个新的 Function 实例。
TrustedScript 实例或字符串,用于指定函数将作为形式参数名称使用的名称。该值必须对应于一个有效的 JavaScript 参数(可以是普通的标识符、剩余参数或解构参数,也可选择使用默认参数),或用逗号分隔的此类字符串的列表。
由于参数的解析方式与函数表达式相同,所以接受空白和注释。例如:"x", "theValue = 42", "[a, b] /* 数字 */" 或 "x, theValue = 42, [a, b] /* 数字 */"。("x, theValue = 42", "[a, b]" 也是正确的,虽然有些难以阅读。)
functionBody包含构成函数定义的 JavaScript 语句的 TrustedScript 或字符串。
函数参数无法被解析为有效的参数列表,或 functionBody 无法被解析为有效的 JavaScript 语句。
TypeError当通过 CSP 强制使用受信任类型且未定义默认策略,而任意参数为字符串。
使用 Function 构造函数创建的 Function 对象会在函数创建时完成解析。这比用函数表达式或函数声明创建一个函数并在代码中调用它的效率要低,因为使用表达式或声明创建的函数会和其他的代码一起被解析。
除最后一个外,传递给函数的所有参数都被当作要创建的函数中参数的标识符的名称,并按照它们被传递的顺序进行处理。函数将被动态编译为一个函数表达式,其源代码会按下述形式组装:
你可以通过调用函数的 toString() 方法来观察。
然而,与普通的函数表达式不同,anonymous 这个名字不会被添加到 functionBody 的作用域中,因为 functionBody 只能访问全局作用域。如果 functionBody 不在严格模式中(主体本身需要有 "use strict" 指令,因为它不从上下文中继承严格性),你可以使用 arguments.callee 来指代函数本身。另外,你可以将递归部分定义为一个内部函数:
请注意,组装后的源代码的两个动态部分——参数列表 args.join(",") 和 functionBody——将首先被分别解析,以确保它们在语法上都是有效的。这可以防止类似注入的尝试。
该方法可用于执行传递给任何参数的任意输入。如果输入是用户提供的可能不安全的字符串,这是跨站脚本攻击(XSS)的潜在载体。例如,以下示例假设 untrustedCode 是由用户提供的:
对于指定了 script-src 或 default-src 的内容安全策略(CSP)的网站默认会阻止此类代码运行。如果你必须允许通过 Function() 运行脚本,可通过始终传递 TrustedScript 对象而不是字符串,并使用 require-trusted-types-for CSP 指令来强制使用受信任类型以缓解这些问题。这可以确保输入经过转换函数进行处理。
要允许 Function() 运行,你还需要在 CSP 的 script-src 指令中指定 trusted-types-eval 关键字。unsafe-eval 关键字也允许 Function(),但安全性远低于 trusted-types-eval,因为它甚至会在不支持受信任类型的浏览器上允许执行。
例如,你的网站的 CSP 配置可能如下所示:
转换函数的行为取决于具体需要用户提供脚本的用例。如果可能,你应该将允许的脚本严格限定为仅包含你信任的代码。如果无法做到这一点,你可以在提供的字符串中允许或阻止某些函数的使用。
请注意,为了简洁起见,这些示例省略了受信任类型的使用。如需查看采用推荐方法的代码,请参阅 eval() 中的使用 TrustedScript。
以下代码创建了一个接受两个参数的 Function 对象。
参数 a 和 b 是在函数体 return a + b 中使用的正式参数名称。
| ECMAScript® 2027 Language Specification # sec-function-constructor |
启用 JavaScript 以查看此浏览器兼容性表。