有以下这样一个字符串,如何把它当作代码来执行? const code = 'console.log('hello world')'
你可能第一时间想到用eval ,其实不止这一种,下面一一来列举,并得出它们的区别。 1. evalconst a = 1 // 全局变量a function exec(code) { const a = 2 // 局部变量a evel(code) } exec('console.log('a', a)') // 打印a console.log('测试同步还是异步')
结论:evel是「同步」代码,读取「当前」作用域的变量。
2. new FunctionFunction 构造函数可以接收一段代码片段作为函数体,然后动态创建一个函数并返回。
const a = 1 // 全局变量a function exec(code) { const a = 2 // 局部变量a const fun = new Function(code) fun() } exec('console.log('a', a)') // 打印a console.log('测试同步还是异步')
结论:new Function是「同步」代码,读取「全局」作用域的变量。
3. script标签动态创建一个script 标签,将字符串代码赋值给innerHTML。 const a = 1 // 全局变量a function exec(code) { const a = 2 // 局部变量a const script = document.createElement('script') script.innerHTML = code console.log(script) document.body.appendChild(script) } exec('console.log('a', a)') // 打印a console.log('测试同步还是异步')
![图片](http://image109.360doc.com/DownloadImg/2023/11/1309/275260749_3_20231113094239195.png) 结论:和第二种一样,script标签是「同步」代码,读取「全局」作用域的变量。但这样会额外创建一个标签,优先推荐new Function。 4. 使用setTimeoutsetTimeout 第一个参数不仅可以传入一个函数,也可以传入一个字符串代码片段。
const a = 1 // 全局变量a function exec(code) { const a = 2 // 局部变量a setTimeout(code, 0) } exec('console.log('a', a)') // 打印a console.log('测试同步还是异步')
结论:是「异步」代码,读取「全局」作用域的变量。
❝ 来源:https://v.kuaishou.com/awNFLR
|