以下是一个使用 Function
构造函数生成可执行 JavaScript 代码的工具函数,支持传入作用域对象,并提供测试用例:
工具函数实现
/**
* 在指定作用域中执行代码
* @param {string} code 要执行的代码(需包含 return 语句或表达式)
* @param {Object} scope 作用域对象(键值对形式的变量环境)
* @returns 代码执行结果
*/
function executeInScope(code, scope = {}) {
// 提取作用域对象的键和值
const keys = Object.keys(scope);
const values = keys.map(key => scope[key]);
try {
// 动态创建函数,将作用域的键作为参数,代码作为函数体
const func = new Function(...keys, `return (() => { ${code} })()`);
// 调用函数并传入作用域的值
return func(...values);
} catch (error) {
throw new Error(`代码执行失败: ${error.message}`);
}
}
测试用例
// 测试用例 1: 基本变量访问
const scope1 = { a: 1, b: 2 };
const result1 = executeInScope('return a + b;', scope1);
console.log('Test 1:', result1); // 输出: Test 1: 3
// 测试用例 2: 变量不存在时抛出错误
const scope2 = { a: 1 };
try {
executeInScope('return a + b;', scope2);
} catch (error) {
console.log('Test 2:', error.message); // 输出: Test 2: 代码执行失败: b is not defined
}
// 测试用例 3: 修改对象属性(按引用传递)
const scope3 = { obj: { value: 10 } };
executeInScope('obj.value = 20;', scope3);
console.log('Test 3:', scope3.obj.value); // 输出: Test 3: 20
// 测试用例 4: 函数内部变量不影响外部作用域
const scope4 = { x: 5 };
executeInScope('let y = 10; x = y;', scope4);
console.log('Test 4:', scope4.x); // 输出: Test 4: 10 (x 被修改)
console.log('Test 4:', scope4.y); // 输出: Test 4: undefined (y 不存在)
// 测试用例 5: 支持复杂表达式和运算
const scope5 = { base: 100 };
const result5 = executeInScope(
'return Array.from({ length: 3 }, (_, i) => base + i);',
scope5
);
console.log('Test 5:', result5); // 输出: Test 5: [100, 101, 102]
关键特性说明
-
作用域隔离
- 通过
Function
构造函数将作用域对象的键作为参数传入,值作为局部变量。 - 代码中无法访问外部作用域,除非显式传入(实现沙箱环境)。
- 通过
-
返回值处理
- 代码需包含
return
语句或表达式才能获取结果。 - 例如:
executeInScope('a * b', { a: 2, b: 3 })
需改为executeInScope('return a * b;', { a: 2, b: 3 })
。
- 代码需包含
-
引用类型传递
- 对象属性按引用传递,内部修改会影响外部作用域(如测试用例 3)。
- 基础类型按值传递,内部修改不影响外部(如测试用例 4)。
-
错误处理
- 使用
try/catch
捕获语法错误或运行时异常(如访问未定义变量)。
- 使用
安全注意事项
-
避免执行不可信代码
- 此工具会直接执行传入的代码字符串,存在代码注入风险,需确保代码来源可信。
-
性能影响
- 动态创建函数有一定性能开销,避免在高频场景使用。
-
严格模式限制
- 若代码使用
use strict
,未声明的变量会直接报错(如测试用例 2)。
- 若代码使用
适用场景
- 动态配置计算(如从数据库读取公式并计算)。
- 插件系统或用户自定义脚本执行。
- 单元测试中的隔离环境验证。
通过此工具函数,可以安全地在隔离作用域中执行动态代码,同时灵活控制变量环境。