I have several script blocks depend on each other. I need to perform them in one scope.
My attempt:
var scopeWrapper = {};
with(scopeWrapper) {
(function() {
this.run = function(code) {
eval(code);
};
}).call(scopeWrapper);
}
scopeWrapper.run('function test() { alert("passed"); }');
scopeWrapper.run('test();');
I get 'test is not defined' error. It seems that the code is executed in different scopes. Why is this happening?
Edit: Bergi pointed out my original answer was wrong, he is correct. Since
eval
runs in its own scope and the function constructor still runs in function scope according to the spec this is not possible with either.While I have done this sort of thing myself several times with node.js using the
vm
module where you get much finer grain of control over where your code executes, it seems browsers require a different approach.The only way you can share variables in such a way is to do so in the global scope of JavaScript execution (possibly, in an iframe). One way you could do this is script tag injection.
(here is this code in action)
As for the scope wrapper, instead of injecting them in the same frame inject them in another
iframe
. That will scope their window object to that iframe and will allow you to share context.I humbly apologize for my previous answer, I misread the spec. I hope this answer helps you.
I'm leaving my previous answer here because I still believe it provides some insight into how
eval
and theFunction
constructor work.When running code in non-strict mode
eval
runs in the current context of your page After your function declaration is done, the scope it was declared in dies, and with it the function.Consider using the Function constructor and then
.call
ing itIn your case that would be something like:
Here is a reference directly from the spec:
If this code is run in the node.js consider using the vm module. Also note that this approach is still not secure in the way it'll allow code you run to change your code.
test
only exists in the scope ofthis.run
and only at call time :Each call of
run
creates a new scope in which eachcode
is evaluated separately.