例如:
(function() {
var proxied = window.eval;
window.eval = function() {
return proxied.apply(this, arguments);
};
})();
但是这段代码无效。
答案 0 :(得分:12)
eval
很神奇。与“真实”函数不同,它可以在调用者中读取和写入局部变量:
function foo() {
var a= 1;
eval('a+= 1');
alert(a); // 2
}
将eval
替换为代理函数,您遇到了问题:a+= 1
在proxied
函数范围内执行,而不是foo
。取决于可能导致值丢失的损坏代码中发生的事情,代理的本地,偶然全局变量等的损坏。
因此,无法用完全正常工作的代理替换eval
。 (对于不需要当地人的简单案例,你可以侥幸逃脱。)
答案 1 :(得分:10)
你做不到。 (有一种有限的方式,但它非常有限,并没有保持bobince talks about的魔力。)
eval
在至少一个主要实现中不是真正的JavaScript函数(IE的JScript,至少不是通过IE7;还没有测试过新的IE8版本),所以马上就开始了遇到麻烦,因为你无法通过apply
来调用原文(不是那对eval
非常重要)。
最近的ECMAScript 5规范明确禁止在严格模式下覆盖eval
(而不是你在那里使用严格模式),这让我怀疑非常好的理由没有压倒它。
答案 2 :(得分:5)
虽然不可移植,但以下方法适用于某些地方,否则它不会(因为它满足ES5的要求A)它在MemberExpression中被检索为参考,而不是值和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
。自己调查一下。
答案 3 :(得分:2)
我在FireFox 3.6.2中试过这个并且它似乎有效。
我直接在FireBug命令行中输入了这个:
var proxied = eval;
eval = function() { alert("ha"); return proxied.apply(this, arguments);};
eval(7);
答案 4 :(得分:0)
也许我没有正确理解这个问题,但是我"覆盖" [{'close': '6/1', 'gross': '$70,165,972', 'open': '1/27', 'title': "Big Momma's House 2"}, {'close': '3/12', 'gross': '$62,318,875', 'open': '1/20', 'title': 'Underworld: Evolution'}, {'close': '2/16', 'gross': '$47,326,473', 'open': '1/6', 'title': 'Hostel'}, {'close': '5/4', 'gross': '$47,144,110', 'open': '1/27', 'title': 'Nanny McPhee'}, {'close': '5/11', 'gross': '$42,647,449', 'open': '1/13', 'title': 'Glory Road'}, {'close': '3/9', 'gross': '$38,399,961', 'open': '1/13', 'title': 'Last Holiday'}, {'close': '4/13', 'gross': '$17,127,992', 'open': '1/27', 'title': 'Annapolis'}, {'close': '3/30', 'gross': '$14,734,633', 'open': '1/13', 'title': 'Tristan and Isolde'}, {'close': '3/9', 'gross': '$11,967,000', 'open': '1/20', 'title': 'End of the Spear'}, {'close': '6/25', 'gross': '$10,407,978', 'open': '1/27', 'title': 'Roving Mars (IMAX)'}, {'close': '2/23', 'gross': '$6,090,172', 'open': '1/6', 'title': "Grandma's Boy"}, {'close': '1/22', 'gross': '$2,405,420', 'open': '1/6', 'title': 'BloodRayne'}, {'close': '4/6', 'gross': '$2,197,694', 'open': '1/27', 'title': 'Rang De Basanti'}, {'close': '5/18', 'gross': '$1,439,972', 'open': '1/20', 'title': 'Why We Fight'}, {'close': '5/4', 'gross': '$1,253,413', 'open': '1/27', 'title': 'Tristram Shandy: A Cock and Bull Story'}, {'close': '3/9', 'gross': '$888,975', 'open': '1/20', 'title': 'Looking for Comedy in the Muslim World'}, {'close': '3/23', 'gross': '$672,243', 'open': '1/27', 'title': 'Imagine Me and You'}, {'close': '1/29', 'gross': '$332,491', 'open': '1/13', 'title': 'Zinda'}, {'close': '3/9', 'gross': '$274,245', 'open': '1/20', 'title': 'Dirty'}, {'close': '5/4', 'gross': '$196,857', 'open': '1/6', 'title': 'Fateless'}, {'close': '2/23', 'gross': '$145,626', 'open': '1/27', 'title': 'Bubble'}, {'close': '3/23', 'gross': '$78,378', 'open': '1/27', 'title': 'Manderlay'}, {'close': '2/12', 'gross': '$65,429', 'open': '1/20', 'title': 'The Real Dirt on Farmer John'}, {'close': '2/26', 'gross': '$55,398', 'open': '1/13', 'title': 'That Man: Peter Berlin'}, {'close': '8/24', 'gross': '$53,580', 'open': '1/27', 'title': 'La Petite Jerusalem'}, {'close': '2/2', 'gross': '$29,710', 'open': '1/13', 'title': 'Henri Cartier-Bresson: The Impassioned Eye'}, {'close': '4/6', 'gross': '$24,038', 'open': '1/13', 'title': 'When the Sea Rises'}, {'close': '1/16', 'gross': '$20,055', 'open': '1/11', 'title': 'State of Fear'}, {'close': '4/9', 'gross': '$17,341', 'open': '1/13', 'title': 'Film Geek'}, {'close': '3/30', 'gross': '$16,377', 'open': '1/13', 'title': "April's Shower"}, {'close': '1/29', 'gross': '$11,290', 'open': '1/27', 'title': 'Live Freaky! Die Freaky!'}, {'close': '1/26', 'gross': '$5,716', 'open': '1/20', 'title': 'Pizza'}]
创建eval()
函数,其中包含原始myEval()
并执行eval()
中的添加步骤。
myEval()
答案 5 :(得分:-1)
你不仅不应该这样做,而且我认为你可能不会这样做。首先,eval是一个全局函数,因此不是窗口的成员(如上所述)。其次,作为一个全局功能,它很可能是硬连线到VM并且不能被覆盖。