把字符串当做js代码执⾏的⽅法
字符串还能当做javascript代码来执⾏?你能想到哪些⽅法?
1、setInterval("要执⾏的字符串",500);
window对象的⽅法既可以传字符串,也可以传函数。该函数第⼀个参数传字符串容易引起内存泄漏,尽量避免这样写。
2、setTimeOut("要执⾏的字符串",500);
window对象的⽅法既可以传字符串,也可以传函数。该函数第⼀个参数传字符串容易引起内存泄漏,尽量避免这样写。
3、eval("要执⾏的字符串");
4、new Function("要执⾏的字符串");
5、<script>"要执⾏的字符串"</script>
6、es6的import
下⾯主要说说Javascript的全局函数eval()和new Function()构造函数。
⼀、eval()
eval()可以动态解析和执⾏字符串,它直接把字符串当做Javascript代码执⾏,eval函数接收⼀个参数str,如果str不是字符串,则直接返回str,否则执⾏str语句。如果str语句执⾏结果是⼀个值,则返回此值,否则返回undefined。
JavaScript规定,如果⾏⾸是⼤括号,⼀律解释为语句(即代码块)。如果要解释为表达式(即对象),必须在⼤括号前加上圆括号。
eval('{foo: 123}') // 123
eval('({foo: 123})') // {foo: 123}
1、执⾏作⽤域
var a = 'global scope';
function b(){
var a = 'local scope'
eval('console.log(a)'); //local scope
}
b();
eval中的代码执⾏时的作⽤域为当前作⽤域,它可以访问到函数中的局部变量,不能访问全局变量。
如果需要,⾃⼰可以封装⼀个函数,让eval能访问全局。
var myNameSpace = {};
myNameSpace.Eval = function(code){
if(!!(window.attachEvent && !window.opera)){
//ie
execScript(code);
}else{
//not ie
window.eval(code);
}
}
传递到eval()中的字符串:如果eval()是被直接调⽤的,this指的是当前对象;如果eval()是被间接调⽤的,this就是指全局对象。eval() ⽅法可以将字符串转换为JavaScript 代码并运⾏。
//eval()的直接调⽤
eval('...')
//eval()的间接调⽤
eval.call(null, '...')
window.eval('...')
(1, eval)('...')
(eval, eval)('...')
2、能否携带with表达式
在严格模式下,eval解析function的字符串中不允许携带with(x)表达式。
字符串截取 js3、安全性
<script>
var a = 1;
eval("var a=2;");  //改变了当前域的变量a
alert(a);
</script>
《⾼性能Javascript》⼀书指出,在代码中使⽤eval是很危险的,特别是⽤它执⾏第三⽅的JSON数据(
其中可能包含恶意代码)时。应该尽可能使⽤JSON.parse()⽅法解析字符串本⾝,该⽅法可以捕捉JSON中的语法错误,并允许你传⼊⼀个函数,⽤来过滤或转换解析结果。eval⾮常耗性能,解析成JS代码要耗能,执⾏时也要耗能。
⼆、new Function()
new Function(arg1, arg2, ..., argN, function_body);中的参数和函数体都以字符串形式传⼊。
new Function()可以动态解析和执⾏字符串,它把传⼊的字符串封装为anonymous匿名函数并返回,直到调⽤这个返回函数时,才会执⾏字符串所要执⾏的操作。编程中并不经常⽤到,但有时候应该是很有⽤的。
1、执⾏作⽤域
var a = 'global scope';
function b(){
var a = 'local scope';
(new Function('','console.log(a)'))(); //global scope
}
b();
new Function中的代码执⾏时的作⽤域为全局作⽤域,不论它在哪个地⽅被调⽤,它访问的都是全局变量a,它⽆法访问b函数内的局部变量。
2、能否携带with表达式
在严格模式下,new Function()的字符串中可以携带with(x)表达式,因为new Function产⽣的是global 作⽤域下的函数,默认是⾮严格模式。
3、安全性
<script>
var a = 1;
new Function("var a=3;")();  //不改变当前作⽤域的变量
alert(a);
</script>
三、总结
综上,可以发现使⽤new Function()运⾏字符串会好⼀些,这也就是为什么很多模板引擎采⽤new Function(),⽽没有⽤eval()的原因吧

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。