运行时代码求值
JavaScript有几种运行机制,每种都有不同的使用上下文,这些不同的代码求值方式包括:
eval函数
函数构造器
定时器
script标签元素
在查看这些机制时,我们将讨论代码求值的作用域,并学习在运行时运行代码求值的安全实践。
用eval()方法进行求值
eval方法可能是运行时代码求值的最常用的方式了,作为定义在全局作用域内的eval方法,该方法将在当前上下文内,执行所传入字符串形式的代码。执行返回结果则是最后一个表达式的执行结果。
var a = eval("5 + 5"); (function () { eval('var ninja = 6'); })() var b = eval('3+4; 5+6');
测试上面代码,感受eval运行。 应该指出的是,任何不是简单变量,原始值,赋值语句的内容都需要在外面包一个括号,以便返回正确的结果。例如,如果我们想使用eval()创建一个简单的对象,可能会编写如下的语句:
var o = eval('{ninja: 1}');
但是结果不是我们期望的,需要加一个括号,如下:
var o = eval('({njnja: 1})');
我们创建函数通常不会使用eval的方式,但是如果我们不知道要创建的函数具体的什么内容,我们可能需要在运行时生成代码或者从别人哪里得到一些代码。
就像我们用普通方式在特定作用域内创建函数一样,eval()创建的函数会继承该作用域的闭包,局部作用域内执行eval()时的衍生结果。
用函数构造器进行求值javaScript中所有的函数都是Function的实例,可以直接使用Function构造器来实例化函数,如下所示:
var add = new Function('a', 'b', 'return a + b;');
Function构造器可变参数列表的最后一个参数,始终是要创建函数的函数题内容。前面的参数则表示函数的形参名称。所以,上述等价如下:
var add = function (a, b) { return a + b; }
虽然功能等同,但采用Function构造器方式有一个明显的区别,函数体由运行时字符串所提供。 另一个重要区别是使用Function构造器创建函数的时候,不会创建闭包。在不想承担任何不相关闭包的开销时,这可是一件好事。
用定时器进行求值定时器可以传递一个内联函数或函数引用,这是推荐使用的方式,但是这些方法也可以接受字符串的传入,从而在定时器触发的时候进行求值。示例如下:
var tick = window.setTimeout('alert("hi !")', 100);
使用这种方式的情形很罕见(大致相当于new Function()的使用方式) ,他的使用会让人失望,除非要求值的代码必须是运行时字符串。
上一篇: Ajax初试之读取数据篇实现代码