只是想分享我尴尬的解决方案。这个想法是从父函数的其余部分构造新函数并在eval
.
function cc(fnname, ctxname) {
'use strict';
var __evalfn = function () {
'use strict';
var __fn = __fnname,
__ctx = __ctxname,
__fnStr = __fn.toString(),
__cccall = 'return eval(cc("'+__sfnname+'", "'+__sctxname+'"));',
__cccallPos = __fnStr.indexOf(__cccall),
__newFn = '(function () { var ',
__decl = [], __restBody;
if (__cccallPos === -1) { throw new Error("Can't find cc call"); }
__restBody = __fnStr.slice(__cccallPos+__cccall.length);
for (var __k in __ctx) {
__decl.push(__k + '=' + __sctxname + '['+JSON.stringify(__k)+']');
}
__newFn += __decl.join(',') + ';';
__newFn += __restBody;
__newFn += ')()';
return eval(__newFn);
},
__evalStr = __evalfn.toString()
.replace(/__fnname/g, fnname)
.replace(/__sfnname/g, JSON.stringify(fnname))
.replace(/__ctxname/g, ctxname)
.replace(/__sctxname/g, JSON.stringify(ctxname));
return '('+__evalStr+')()';
}
var fn = function () {
var a=10, ctx = {'b':10, 'c':'hello'};
return eval(cc("fn", "ctx"));
console.log(a,b,c);
return a+b;
};
> fn();
> 10 10 "hello"
> <- 20
它将要求您return eval(cc("fn", "ctx"));
输入您的功能。fn
是您使用的变量保持函数的名称cc
。ctx
是持有新绑定的对象的名称。一个优点cc
是它允许 中的任何值ctx
,从数字和字符串到使用用户定义的构造函数创建的对象。