把字符串当做javascript代码执行

字符串还能当做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)表达式。
3、安全性

<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()的原因吧。


转载于:https://www.cnblogs.com/camille666/p/js_string_as_code_exec.html

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要将字符串作为程序二进制代码执行,需要使用一些底层的编程技术,具体取决于所使用的编程语言和平台。以下是一般的步骤: 1. 将字符串转换为对应的二进制数据:首先,你需要将字符串转换为其对应的二进制表示。这可以通过编码和解码技术来实现,例如使用Base64编码或自定义的编码方案。 2. 分配内存空间:在执行二进制代码之前,你需要在内存中分配足够大的空间来存储二进制数据。这可以通过调用特定的内存分配函数来实现,例如malloc()。 3. 将二进制数据复制到分配的内存空间:将转换后的二进制数据复制到先前分配的内存空间中。这可以使用内存拷贝函数(例如memcpy())来完成。 4. 设置内存区域可执行权限:默认情况下,分配的内存区域可能被设置为不可执行。因此,你需要使用特定的系统调用或API来设置内存区域的可执行权限。具体的方法取决于所使用的操作系统和编程语言。 5. 转换为函数指针并执行:将分配的内存区域视为函数指针,并通过调用该指针来执行二进制代码。这可以通过将内存区域中的地址转换为函数指针类型,并调用该指针来实现。 请注意,这种技术涉及到底层的编程概念和操作系统相关的功能。因此,确保你对所使用的编程语言和平台有足够的了解,并小心操作,以避免安全问题和意外的行为。此外,这种技术在大多数情况下是不推荐的,应该谨慎使用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值