有没有办法在执行时手动更改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
能够在调用callFunciton
时访问在CCD_5中定义的变量test
。然而,由于作用域和执行上下文在Javascript中的工作方式,它不能以这种方式工作。
我正在为callFunction
寻找一种方法,在callee()
调用的执行上下文中插入一个名为test
的变量。
在这个最小的例子中,当然可以将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();
});
}
到目前为止,我找到了三种解决这个问题的方法,但我都不喜欢:
- 在回调中定义参数,并且只在callbackParams中定义它们的类型,并根据它们在函数声明中的顺序进行索引。缺点:参数必须在两个地方声明
- 在回调中使用
this.paramname
而不是仅使用paramname
,并在`handleEvent()中使用CCD11。缺点:对插件不透明 - 在调用CCD_ 13中的CCD_。缺点:非常难看的变通方法
想法?
您可以使用with
语句。请注意,在严格模式下,它是缓慢且被禁止的。
var func;
(function () {
func = function func() {
with(func.variables) {
console.log(test);
}
}
})();
function callFunction (callee) {
callee.variables = {test: "foobar"};
callee();
callee.variables = null;
}
callFunction(func);