前端大屏原理系列:创建动态函数

272 阅读2分钟

本文是《前端大屏原理系列》第四篇:创建动态函数。

本系列所有技术点,均经过本人开源项目 react-big-screen 实际应用,欢迎 star (*´▽`)ノノ.

一、效果演示

2025-05-20_16-14-29.gif

二、实现原理

运行时创建函数主要为了修改组件传递参数的数据格式,或者实现一些更复杂的处理逻辑。因为大屏多组件联动传输的数据格式是固定的,通过函数转换数据格式可以兼容更多组件,而无需修改源代码。常见的js创建动态函数方式有两种:evalnew Function。(我们最终要实现的目标是:动态创建 main 函数。)

本项目使用 new Function 实现,eval 存在安全问题不推荐!

example.png

2.1 eval

eval 主要用来执行一段js代码,其可以读取、修改「调用作用域」,因此是不安全的。风险如下:

// 风险一:获取调用作用域
const name = "xxx";
eval("console.log(name)") // xxx
// 风险二:修改调用作用域
let name = "xxx";
eval("name = '222'")
console.log(name) // 222

下面是创建main函数的实现代码:

const text = `
let len = 5;

function main () {
  return Array(len).fill(1);
}
`

// 使用匿名函数创建局部作用域,避免与调用作用域中的变量同名导致报错。
function getMainByEval(text: string): Function | undefined {
    let fn;
    eval(`(() => {
      ${text};
      fn = main;
    })()`)
    return fn;
}

// 测试函数
const createArray = getMainByEval(text);
console.log(createArray()); // [1,1,1,1,1]

2.2 new Function

调用 Function 的构造函数创建动态函数,其会在全局作用域创建闭包,所以只能访问「自身局部作用域」或「全局作用域」。其不能读取、修改当前「调用作用域」,因此比eval更安全。实现代码如下:

function getMainByFunction(text: string): Function | undefined {
    return new Function(`${str}; return main;`)();
}

// 测试
const createArray = getMainByFunction(text);
console.log(createArray()); // [1,1,1,1,1]

【前端大屏原理系列】

react-big-screen 是一个从0到1使用React开发的前端拖拽大屏开源项目。此系列将对大屏的关键技术点一一解析。包含了:拖拽系统实现、自定义组件、收藏夹、快捷键、可撤销历史记录、加载远程组件/本地组件、自适应预览页、布局容器组件、多组件联动(基于事件机制)、成组/取消成组、多子页面切换、i18n国际化语言、鼠标范围框选、... ... 等等。

演示地址:点击访问