var foo = (function(){
var x = "bar";
return function(){
console.log(x);
};
})();
console.log(foo.toString()); // function() {console.log(x);}
(foo)(); // 'bar'
eval('(' + foo.toString()+')()')); // error: x is undefined
Why isn't the var x recorded as "bar" in foo.toString()?
foo has a behavior that does not match its toString() value. foo always prints "bar", but looking at foo.toString() would not tell you this.
Is it related to this? If a decision was made not to decompile a function to get its toString() value, why not include the resolution of objects which rely on an external function's scope?
Is there a way to use the old method of decompilation to get the actual code behind a given function?
You are executing the anonymous function, so the return value is assigned to foo. If you use
var foo = function(){
var x = "bar";
return function(){
console.log(x);
};
};
foo.toString() shows the anonymous function and
foo().toString() the returned function
Your eval creates a new function from foo.toString()1, not in any way related to the scope of the initial scope [of the anonymous function that created foo], and executes that, so it results in a ReferenceError concerning x. There's nothing strange about that.
1 eval("function (){console.log(x);})()")