Given the following snippet of javascript in a scope:
var x = 10;
function sayx() {
alert(x);
}
sayx();
You would of course expect a message box printing '10', you could do multiple function nesting to interact with how 'x' is determined, because when resolving what x is the environment walks up the scope chain.
You can even do a level of 'recompilation' with eval to inject new scopes at runtime.. for example:
var x = 10;
function sayx() {
alert(x);
}
function wrap(f) {
return eval('(function() { var x = 20;(' + f + ')(); })');
}
wrap(sayx)();
This works because the function will have its toString function called which will return the 'original' source.. thus we essentially create a wrapped version of the function that has a new scope that overrides x.. the result will be an alert box that prints '20' and not '10'.
However, on the surface this could appear to work but the scope chain is broken, the next item in the chain is no longer the same because the function 'f' is now defined at a different location.. even worse is that the scope chain it has inherited could contain many references that the calling function shouldn't have access to.
So, is there a more supported, workable way to inject a scope item? something like:
function withScope(f, scope) { ??? }
---
var x = 10, y = 10;
function dothemath() {
alert(x + y);
}
var haxthemath = withScope(dothemath, { x: 9000 });
haxthemath(); // 9010 not 20
I'm guessing the answer is 'no', some may argue there are 'security' issues with such scope injection, but considering you can do the trick anyway (albeit severely broken) I don't think it is..
The benefits of this would be that you can essentially fake your own pseudo variables.
Thanks in advance.
Edit, just the clarify a little, imagine I wanted to 'withScope' a function that had the following scope chain:
Window - window properties
Object - { var x = 10 }
Object - { var y = 5 + x }
I would like to be able to get a function back that effectively had the same chain + a scope I provide.. ie:
withScope(somefunc, { foo: 'bar' })
Would give me
Window - window properties
Object - { var x = 10 }
Object - { var y = 5 + x }
Ext scope - { foo = 'bar' }
All prior standing variables would be found because my extended scope doesn't say anything about them.