有没有办法在执行时手动更改 Javascript 函数的执行上下文?
我不是在谈论将this
引用更改为指向不同的对象 - 我知道这可以通过Function.prototype.call()/apply()
.
我说的是更改函数可访问的变量,或者更具体地说,授予对函数定义范围之外的变量的访问权限。
例子:
var func;
(function () {
func = function () {
alert(test); // no variable called "test" defined, it will
// result in a ReferenceError when func() is called
}
})();
function callFunction (callee) {
var test ='foobar';
callee(); // callee does not have access to "test"
}
callFunction(func);
在此示例中,我希望该函数func
能够在调用它时访问test
定义的变量callFunciton
。但是,由于范围和执行上下文在 Javascript 中的工作方式,它不能那样工作。
我正在寻找一种方法callFunction
来插入在调用test
的执行上下文中callee()
调用的变量。
在这个最小的例子中,当然可以将 test 作为参数添加到 func()。
然而,我的用例是一个带有插件基础设施的框架,其中插件可以指定回调以及它们采用的参数 - 以及参数类型。然后框架负责将请求的数据转换为请求的类型并将它们提供给回调。这应该对插件完全透明。
伪代码:
插入
function callback {
alert(user.name);
alert(number);
};
var callbackParams = [
{name : 'user', type : User},
{name : 'number', type : Number}
];
defineCallback('event', callback, callbackParams);
框架
var on = {
event : [];
}
var User = function (name) {
this.name = name;
}
function defineCallback (event, callback, params) {
on[event].push({
callback : callback;
params : params;
});
}
function handleEvent(event) {
on[event].forEach(function (handler) {
for (param of handler.params) {
// 1) gather data
// 2) create Object of correct type as specified in
// param.type
// 3) insert variable called param.name into
// execution context of handler.callback
}
handler.callback();
});
}
到目前为止,我找到了三个解决这个问题的方法,我都不喜欢:
- 在 callback 中定义参数,并且只在 callbackParams 中定义它们的类型,按它们在函数声明中的顺序索引。缺点:参数必须在两个地方声明。
- 使用
this.paramname
而不是仅paramname
在回调中使用,并.call()/.apply()
在 `handleEvent() 中使用。缺点:对插件不透明。 - 在调用之前将变量分配给全局范围,
handler.callback()
然后handleEvent()
再次删除它们。缺点:非常难看的解决方法。
想法?