(function() {
var proxied = window.eval;
window.eval = function() {
return proxied.apply(this, arguments);
};
})();
但是这段代码没有起作用。
(function() {
var proxied = window.eval;
window.eval = function() {
return proxied.apply(this, arguments);
};
})();
但是这段代码没有起作用。
eval
是魔法般的函数。与“真正的”函数不同,它可以读取和写入调用者的本地变量:
function foo() {
var a= 1;
eval('a+= 1');
alert(a); // 2
}
用代理函数替换eval
会出现一个问题:执行a+=1
的作用域是proxied
函数而不是foo
。根据被评估代码中发生的情况,这可能导致值丢失、代理的本地损坏、意外的全局变量等问题。
因此,无法用完全可用的代理替换eval
。(对于简单的情况,如果不需要使用局部变量,可能可以尝试使用)
MyEval
来替换eval
,但是你需要eval
——MyEval(_=>eval(_))
。 - Pacerier你无法这样做。(虽然有一种 有限的 方法,但非常有限且无法保持bobince 所提到的奇妙效果。)
eval
在至少一个主要实现中不是真正的 JavaScript 函数(IE 的 JScript,至少在 IE7 及之前版本中不是;还没有测试过新的 IE8 版本),因此您将会遇到麻烦,因为您将无法通过 apply
调用原始函数(尽管对于 eval
来说这并不重要)。
最近的 ECMAScript 5 规范在严格模式下明确禁止覆盖 eval
(尽管您在那里未使用严格模式),这使我怀疑不覆盖它的理由是非常充分的。
eval
,因为解释器无法事先确定函数块中是否包含隐藏的eval
使用。如果解释器(尤其是JIT)能够确保函数仅包含简单代码且没有eval
,则可以在生成的代码上执行更广泛的优化。 - bobince虽然不是可移植的,但以下方法在某些情况下可以起作用,否则可能无法满足ES5的要求:A)它必须以MemberExpression中的Reference形式检索,而不是Value形式;B)它会导致“标准内置函数”。—ES5 #15.1.2)
(function() {
var proxied = window.eval
with({get eval(){ console.log('eval called'); return proxied }}) {
/* client code */
}
})()
如果您可以将客户端代码包装在with()语句中,那么这显然只适用于此;尽管在许多情况下,这不应该很难。显然,同样的方法可以使用另一个带有所有属性的对象来屏蔽window,并使用getter代理的eval。
不支持SpiderMonkey的get语句的环境可能能够使用ES5的defineProperty。请自行了解。
proxied}
中缺少一个 }
。 - johnjohn我尝试在FireFox 3.6.2中进行此操作,看起来可以正常工作。
我直接在FireBug命令行中输入了以下内容:
var proxied = eval;
eval = function() { alert("ha"); return proxied.apply(this, arguments);};
eval(7);
eval()
函数放在内部并在myEval()
中执行其他步骤的myEval()
函数,来“覆盖”eval()
。function myEval = function(value){
//do your stuff here
//for example
try {
value = eval(value)
} catch (error) {
console.log(error)
value = NaN
}
return value
}
不仅你不应该这样做,而且我认为你可能做不到。首先,eval是一个全局函数,因此不是window的成员(就像你上面尝试的那样)。其次,作为全局函数,它很可能已经被硬编码到VM中,无法被覆盖。
window
),并列在第15.1.2.1节中。但确实如此实现的可靠性不高。 - T.J. Crowder