文章目录
- 1、第一种方式:eval
- 2、第二种方式:setTimeout
- 3、第三种方式:创建script 标签插入body
- 4、第四种方式:创建 Function
- 5、对比
- 6、 参考链接
1、第一种方式:eval
语法
eval(string)
参数
string
:一个表示 JavaScript 表达式、语句或一系列语句的字符串。表达式可以包含变量与已存在对象的属性。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>var blockName = 'window作用域'function exec(jsCode) {var blockName = '函数作用域'eval(jsCode)}exec(`console.log('动态执行脚本里面执行 输出blockName',blockName)const res = new Promise((resolve,reject)=>{setTimeout(()=>{resolve('动态执行脚本里面执行 promise 更改状态为 成功')},1000)})res.then(res=>{console.log(res)})`)console.log('动态执行代码后继续执行');</script>
</body></html>
可以看到,eval 是
同步执行
,采用的当前作用域
,在哪执行的就引用那个作用域
2、第二种方式:setTimeout
语法
setTimeout(code)
setTimeout(code, delay)setTimeout(functionRef)
setTimeout(functionRef, delay)
setTimeout(functionRef, delay, param1)
setTimeout(functionRef, delay, param1, param2)
setTimeout(functionRef, delay, param1, param2, /* … ,*/ paramN)
参数
functionRef
:当定时器到期后,将要执行的 functioncode
:一个可选语法,允许你包含在定时器到期后编译和执行的字符串而非函数delay
:延迟时间,可选,单位是毫秒
var blockName = 'window作用域'function exec(jsCode) {var blockName = '函数作用域'// eval(jsCode)setTimeout(jsCode)}exec(`console.log('动态执行脚本里面执行 输出blockName',blockName)const res = new Promise((resolve,reject)=>{setTimeout(()=>{resolve('动态执行脚本里面执行 promise 更改状态为 成功')},1000)})res.then(res=>{console.log(res)})`)console.log('动态执行代码后继续执行');
可以看到
setTimeut
是异步执行,作用域是全局作用域
3、第三种方式:创建script 标签插入body
var blockName = 'window作用域'function exec(jsCode) {var blockName = '函数作用域'// eval(jsCode)// setTimeout(jsCode)let scriptEl = document.createElement('script')scriptEl.innerHTML = jsCodedocument.body.appendChild(scriptEl)}exec(`console.log('动态执行脚本里面执行 输出blockName',blockName)const res = new Promise((resolve,reject)=>{setTimeout(()=>{resolve('动态执行脚本里面执行 promise 更改状态为 成功')},1000)})res.then(res=>{console.log(res)})`)console.log('动态执行代码后继续执行');
可以看出,这个方式,也是
全局作用域
, 同步执行代码
缺点是会在 body 标签里面你创建
script 标签
4、第四种方式:创建 Function
举个例子
const sum = new Function('a', 'b', 'return a + b');console.log(sum(2, 6));
// 输出: 8
语法
new Function(functionBody)
new Function(arg0, functionBody)
new Function(arg0, arg1, functionBody)
new Function(arg0, arg1, /* …, */ argN, functionBody)
参数
argN
:被函数用作形参的名称
。每个名称都必须是字符串
,对应于一个有效的 JavaScript 参数(任何一个普通的标识符、剩余参数或解构参数,可选择使用默认参数),或用逗号分隔的此类字符串的列表。functionBody
:一个包含构成函数定义的 JavaScript 语句的字符串。就是函数体
var blockName = 'window作用域'function exec(jsCode) {var blockName = '函数作用域'// eval(jsCode)// setTimeout(jsCode)// let scriptEl = document.createElement('script')// scriptEl.innerHTML = jsCode// document.body.appendChild(scriptEl)new Function(jsCode)()}exec(`console.log('动态执行脚本里面执行 输出blockName',blockName)const res = new Promise((resolve,reject)=>{setTimeout(()=>{resolve('动态执行脚本里面执行 promise 更改状态为 成功')},1000)})res.then(res=>{console.log(res)})`)console.log('动态执行代码后继续执行');
可以看出也是
同步执行
,全局作用域
5、对比
方式 | 代码执行顺序 | 代码执行时作用域 | 缺点 |
---|---|---|---|
eval | 同步执行 | 执行时候的作用域 | |
setTimeout | 异步执行 | 全局作用域 | |
创建 script 标签插入body | 同步执行 | 全局作用域 | 会在浏览器控制台元素里面看到这个插入的script 标签内容 |
创建 Function | 同步执行 | 全局作用域 |
6、 参考链接
- eval MDN
- setTimeout MDN
- Function MDN