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
为什么var x
未在"bar"
中记录为foo.toString()
?
foo
的行为与其toString()值不匹配。 foo
始终打印“bar”,但查看foo.toString()
不会告诉您这一点。
它与this有关吗?如果决定不对函数进行反编译以获取其toString()值,为什么不包括依赖于外部函数范围的对象的解析?
有没有办法使用旧的反编译方法来获取给定函数背后的实际代码?
答案 0 :(得分:2)
您正在执行匿名函数,因此返回值已分配给foo
。如果你使用
var foo = function(){
var x = "bar";
return function(){
console.log(x);
};
};
foo.toString()
显示匿名函数和
foo().toString()
返回函数
您的eval
从foo.toString()
1 创建新功能,与初始范围的范围无任何关联 [创建foo
]的匿名函数,并执行该函数,因此会产生ReferenceError
x
。这没什么奇怪的。
1 eval("function (){console.log(x);})()")
答案 1 :(得分:2)
由于javascript是函数范围的,因此当它转换为字符串时会丢失其范围信息。因此,此字符串中新创建的函数与原始函数无关。
我的两个解决方法是:
首先,改为使foo成为IIFE,你可以拥有它:
var foo = function(){
var x = "bar";
return function(){
console.log(x);
};
};

然后调用eval('(' + foo.toString()+')()()'),在执行函数并传递时创建范围
或者你可以保留IIFE并在你调用eval('(' + foo.toString()+')')时,使用apply或call方法调用它将x放在上下文对象中或作为参数传入。