使用方式
javascript
//多参数形式
const add1 = new Function('a', 'b', 'return a + b');
// 参数合并形式
const add2 = new Function('a, b', 'return a + b');
// add1 与 add2 等价以下 add 函数,区别参考下文「特点」
const add = (a, b) => a + b;
new Function 创建的函数的特点
1. 在全局作用域中执行
javascript
const x = 10;
function createFunction() {
const x = 20;
// 这个函数只能访问全局作用域,不能访问 createFunction 的局部作用域
return new Function('return x');
}
const func = createFunction();
console.log(func()); // 10
2. 运行时编译
javascript
// 可以从字符串动态创建函数
const operation = 'multiply';
const funcBody = operation === 'add'
? 'return a + b'
: 'return a * b';
const func = new Function('a', 'b', funcBody);
console.log(func(5, 3)); // 15
3. 无法访问外部变量(无闭包)
javascript
function outer() {
const secret = 'hidden';
// 传统函数定义可以访问外部变量
const normalFunc = function() {
return secret;
};
// new Function 不能访问外部变量
const newFunc = new Function('return secret');
console.log(normalFunc()); // 'hidden'
console.log(newFunc()); // ReferenceError: secret is not defined
}
Function 中的 this
默认情况指向全局对象
默认情况下,new Function 创建的函数中 this 指向全局对象,即浏览器中是 window
,Node.js 中是 global
。这也是 Function 的特点,即在全局作用域中执行。
javascript
// 在浏览器中
const func = new Function('return this');
console.log(func()); // Window 对象(浏览器环境)
// 在 Node.js 中
const func = new Function('return this');
console.log(func() === global); // true(Node.js 环境)
严格模式是 undefined
javascript
// 使用严格模式
const func = new Function('"use strict"; return this');
console.log(func()); // undefined
不受调用上下文影响
不会像普通函数那样根据调用方式改变 this
javascript
const obj = {
value: 'object value',
// 普通函数
normalMethod: function() {
return this.value;
},
// new Function 创建的函数
newFunctionMethod: new Function('return this.value')
};
console.log(obj.normalMethod()); // 'object value'
console.log(obj.newFunctionMethod()); // undefined
需要显式绑定
如果想要在 Function 内使用 this,可以通过 call
、apply
或 bind
来指定 this
。
javascript
const obj = { value: 'test' };
const func = new Function('return this.value');
console.log(func.call(obj)); // 'test'
console.log(func.apply(obj)); // 'test'
const boundFunc = func.bind(obj);
console.log(boundFunc()); // 'test'