一般我们代码几乎不会使用到eval, 但凡需要使用到eval的地方,都会代而使用构造器Function生成函数实例的方式,因为eval is evil。eval可以在全局作域下执行代码,也可以在局部作用域(间接调用eval)下执行代码。而使用构造器Function生成函数实例的方式,可以确保我们的代码是在全局作用域下执行。
voidfunction(global){/** * Execute javascript code within specific scope * @param {Function|String} fn Scoped function or expression * @param {Object} imports An object which defines required local variables * @return {Function} Function that can be invoked to run code in specific scope */functionscopedRunner(fn,imports){varrfunc=/^function\s+(?:[^(]*)\(([^)]*)\)\s*{([^]*)}$/;varfound=String(fn).match(rfunc)||[,,'return ('+fn+');'];varargs=found[1]||'';varstmt=found[2]||'';varbody=Object.keys(imports||{}).reduce(function(ret,key,idx){returnret+(idx?', ':'var ')+key+' = $scope["'+key+'"]';},'')+'; return function ('+args+') {'+stmt+'};';returnFunction('$scope',body).call(null,imports);}// define `global.$eval`Object.defineProperty(global,'$eval',{value:function(){returnscopedRunner.apply(null,arguments)();}});// define `Object.prototype.$eval`Object.defineProperty(Object.prototype,'$eval',{value:function(expr){returnglobal.$eval(expr,this);}});}(function(){returnthis;}());
以下是一些关于$eval和Object.prototype.$eval的使用例子。
e.g 1
123456789101112131415161718
// define some global variablesx=10;y=30;voidfunction(){// define some local variablesvara=6,b=7;$eval(function(){// ReferenceError: a is not defined// console.log(a + b);});// ReferenceError: a is not defined// console.log($eval('a + b'));console.log($eval('y / x'));//=> 3}();