[英]Javascript: Execute function with different execution context
Is there a way to change the execution context of a Javascript function manually at execution time? 有没有办法在执行时手动更改Javascript函数的执行上下文?
I am not talking about changing the this
reference to point to a different object - I know this can be done with Function.prototype.call()/apply()
. 我不是在谈论更改
this
引用以指向另一个对象-我知道可以通过Function.prototype.call()/apply()
来完成。
I am talking about changing variables accessible to the function, or to be more specific, granting access to variables that are outside of the scope the function is defined in. 我正在谈论更改函数可以访问的变量,或者更具体地说,是要授予对定义函数范围之外的变量的访问权限。
Example: 例:
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);
In this example, I'd love the function func
to be able to access the variable test
defined in callFunciton
when it is called. 在此示例中,我希望函数
func
能够在被调用时访问在callFunciton
定义的变量test
。 However due to how scope and execution contexts work in Javascript, it doesn't work that way. 但是,由于范围和执行上下文在Javascript中是如何工作的,因此它不是那样工作的。
I am looking for a way for callFunction
to insert a variable called test
in the execution context of the callee()
call. 我正在为
callFunction
寻找一种在callee()
调用的执行上下文中插入称为test
的变量的方法。
In this minimal example, it is of course possible to just add test as a parameter to func(). 在这个最小的示例中,当然可以仅将test作为参数添加到func()。
My use-case however is a framework with a plugin infrastructure, where plugins can specify callbacks and what parameters they take - along with parameter types. 但是,我的用例是一个具有插件基础结构的框架,插件可以在其中指定回调及其所使用的参数-以及参数类型。 The framework then takes care of converting requested data into the requested types and provide them to the callback.
然后,框架负责将请求的数据转换为请求的类型,并将其提供给回调。 This should happen completely transparent to the plugin.
这应该对插件完全透明。
Pseudocode: 伪代码:
Plugin 插入
function callback {
alert(user.name);
alert(number);
};
var callbackParams = [
{name : 'user', type : User},
{name : 'number', type : Number}
];
defineCallback('event', callback, callbackParams);
Framework 构架
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();
});
}
So far, I found three solutions to this problem, and I like neither: 到目前为止,我找到了解决此问题的三种解决方案,但我都不喜欢:
this.paramname
instead of just paramname
in callback, and use .call()/.apply()
in `handleEvent(). this.paramname
而不是paramname
,在`handleEvent()中使用.call()/.apply()
()。 Disadvantage: not transparent to plugins. handler.callback()
in handleEvent()
and delete them again afterwards. handleEvent()
调用handler.callback()
之前,将变量分配给全局范围,然后再删除它们。 Disadvantage: very ugly workaround. Ideas? 有想法吗?
You can use a with
statement. 您可以使用
with
语句。 Be aware it's slow and forbidden in strict mode. 请注意,它在严格模式下是缓慢且禁止的。
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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.