/** * Execute javascript code within specific scope * @param {Function|String} fn scoped function or expression * @param {Object} imports An object defines required local variables * @return {Function} A 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+' = __locals__["'+key+'"]';},'')+'; return function ('+args+') {'+stmt+'};';returnFunction('__locals__',body).call(null,imports);}
The following are some examples.
12345678910
// e.g 1voidfunction(){scopedRunner(function(m,n){varresult=(x+y)+(m+n);console.log('The meaning of life is:',result);//=> 42},{x:10,y:1}).call(null,30,1);}();
123456789
// e.g 2voidfunction(){varresult=scopedRunner('times(a, b)',{a:6,b:7,times:(x,y)=>x*y})();console.log('The meaning of life is:',result);//=> 42}();
123456789
// e.g 3Object.prototype.__eval=function(expr){returnscopedRunner(expr,this)();};voidfunction(){varobj={a:6,b:7,times:(x,y)=>x*y};varresult=obj.__eval('times(a, b)');console.log('The meaning of life is:',result);//=> 42}();
1234567891011121314
// e.g 4vartake=(scope=>scopedRunner(scope.eval,scope.with)());voidfunction(){vara=6,b=7,times=(a,b)=>a*b;// take result out from evaluated value within specific scopevarresult=take({with:{a,b,times},eval:'times(a, b)'});console.log('The meaning of life is:',result);//=> 42}();
1234567
// e.g 5varinvoke=scopedRunner((fn,...args)=>fn.apply(null,args))();voidfunction(){varresult=invoke((a,b)=>a+b,6,7);console.log('The meaning of life is:',result);//=> 13}();