JS 执行脚本
在现在项目中执行脚本的情况比较少。但是如果有这样的要求,我们应该如何实现。
对于这个问题是鉴于有一个项目中实际遇到,就深入了解下。
一、eval
eval 是全局对象的一个函数属性。
eval 接收的是一个字符串的脚本,如果不是字符串,会直接返回。
console.log(eval('2+2')) // 4 console.log(eval(new String('2+2'))) // [String: '2+2']
eval 还有一些很大的问题缺陷:
1、执行较慢(必须调用 JS 解释器)
2、安全问题(使用与调用者相同权限执行代码,这样会导致恶意代码被执行)
所以建议谨慎或者不使用 eval!
二、Function
在 JS 中每一个函数都是 Function 对象。
我们在写代码的时候用的:函数声明、函数表达式、箭头函数等写的都是 Function 对象。
function add(x, y) { return x + y } console.log(add.constructor === Function) // true let add1 = function (x, y) { return x + y } console.log(add1.constructor === Function) // true let add2 = (x,y)=>{ return x + y } console.log(add2.constructor === Function) // true
那么我们也可以直接用 Function 构造函数动态的创建函数。
/** * Function([arg1[,arg2...]],functionBody) * 1、前面的是动态创建函数的参数 * 2、要创建的函数的函数体 */ const adder = new Function('a','b','return a+b') console.log(adder.constructor === Function) // true
Function 和 eval 是有区别的:
1、接收参数不一样:Function 的函数体是可以接收字符对象,eval 只能是字符
2、eval 是直接执行传入的语句等,Function 是创建了一个函数(根据需要是否有返回 return 不能忘记)
3、Function 是在全局执行的(只能访问全局变量和自己变量,创建这个函数的作用域也不可以),eval 有自己调用的作用域(这个地方不安全,会被第三方查看)
const adder1 = new Function('a','b',new String('return a+b')) console.log(adder1(3,4)) // 7 可以接收 String 对象 // 需要在浏览器环境下执行 var x = 5 function createFun() { var x = 10 return new Function('return x;') } const fun1 = createFun() console.log(fun1()) // 5