Is it possible to extend dynamically javascript function scope? I tried without success the following:
function foo()
{
var bar = 12;
return function(x)
{
return eval(x);
}
}
var e = foo();
console.log(e("bar")); // 12
console.log(e("bar = 42;")); // 42
console.log(e("bar")); // 42
console.log(e("var baz = 99;")); // undefined
console.log(e("baz")); // ReferenceError: baz is not defined
If however I remove var
from the line baz = 99
then the baz variable becomes a global (this makes perfect sense to me):
...
console.log(e("baz = 99;")); // 99
console.log(e("baz")); // 99
console.log(baz); // 99 (so baz is just a global)
x.y
requires first looking up x
and then looking for y
inside whatever is found by first lookup - 6502 2012-04-03 20:15
this[name]
is faster and more efficient then accessing name
through closure scop - Raynos 2012-04-03 20:34
prototype
are the fastest in V8 (illogical) and a local function is slower than a function looked up using a local variable with var me = this
idiom (also illogical: me.fibo()
is faster than fibo()
with both me
and fibo
being local vars). Moreover what is faster changes depending on the phase of the moon but consistently across my home 32-bit system and my office 64-bit system. This is the probably the price to pay to such a fast but complex implementation - 6502 2012-04-03 23:00
Everytime you call e("var baz = 4")
, it's creating a variable on the stack of that function call, so it's not going to be available the next time you call it.
If you need to dynamically add variables to the scope, I would use Rayno's suggestions, use a map. http://jsfiddle.net/UVSrD/
function foo()
{
var scope = {};
return function(x)
{
return eval(x);
}
}
var e = foo();
console.log(e("scope.bar = 12")); // 12
console.log(e("scope.bar")); // 12
console.log(e("scope.baz = 14")); // 14
console.log(e("scope.baz;")); // 14
// Not a global
console.log(typeof scope) // undefined
var baz = 99;
was not working... the problem is that the scope I'd like to access is the outer one, not the one of the function returned by foo
. Using a local object is an option but means using a double lookup for every access (first looking up scope
and the looking up the variable or function) - 6502 2012-04-03 20:19
You're creating a closure using this code:
function foo()
{
var bar = 12;
return function(x)
{
return eval(x);
}
}
When you pass in bar your overriding the bar variable that has already been initiated to 12. I'm not sure what your trying to accomplish, but using a closure will retain the outer functions variables.
eval
is modifying a captured variable. The question is if it's possible to add more "captured variables" and local functions later or not - 6502 2012-04-03 19:40
Eval will run in the scope of wherever it is called. The behavior you are seeing is because on this line:
console.log(e("var baz = 99;")); // undefined
you create a var baz = 99 in the local scope of the returned function. The return value of var name = value; isn't anything, you you get undefined. when you subsequently call
console.log(e("baz")); // ReferenceError: baz is not defined
you return a new function, where baz hasn't been defined.
This is kinda cool: http://www.bennadel.com/blog/1926-Exploring-Javascript-s-eval-Capabilities-And-Closure-Scoping.htm
var baz
doesn't work. My question is if it's possible to escape one level and get to the containing scope - 6502 2012-04-03 20:09