【发布时间】:2010-11-10 07:14:42
【问题描述】:
我最近有必要在 javascript 中动态地重写一个 javascript 函数。我做这件事的轻松程度和乐趣让我震惊。
这里我有一些 HTML:
<div id="excelExport1234"
onclick="if(somestuff) location.href='http://server/excelExport.aspx?id=56789&something=else'; else alert('not important');"
>Click here to export to excel</div>
而且我无法更改输出的 HTML,但我需要向该链接添加一个额外的参数。我开始考虑它,并意识到我可以这样做:
excelExport = $('excelExport1234');
if (needParam)
eval('excelExport.onclick = ' + excelExport.onclick.toString().replace("excelReport.aspx?id", "excelReport.aspx?extraParam=true&id") + ';');
else
eval('excelExport.onclick = ' + excelExport.onclick.toString().replace("extraParam=true&", "") + ';');
它就像一个冠军! excelExport.onclick 返回一个函数对象,我将其转换为字符串,并对其进行一些字符串操作。由于它现在是“function() { ... }”的形式,我只是返回并将其分配给 dom 对象的 onclick 事件。不得不使用 eval 有点难看,但是 AFAIK 没有一个 javascript 函数构造函数可以接受一串代码并将其很好地转换为对象。
无论如何,我的意思不是我超级聪明(我不是),我的意思是这很酷。而且我知道 javascript 不是唯一可以做到这一点的语言。我听说 lisp 多年来一直为此目的使用宏。除了真正 grok 宏,你需要真正 grok lisp,而我不 grok,我只是'有点明白'。
所以我的问题是:您可以(轻松)用哪些其他语言动态重写函数,您能给我看一个简单的示例吗?我想看看您还可以在哪些地方做到这一点,以及如何完成了!
(另外,我不知道要标记什么,所以我随机猜测)
【问题讨论】:
-
这就是疯狂。
-
我从来没有说过这是最优雅的事情,但它非常酷。这就像大多数小技巧一样——危险的原因是它们可以依赖编译器实现等,但仍然聪明有趣。
-
你并没有真正重写一个函数。您正在构建一个您评估的字符串。代码将函数分配给某个标识符。许多语言都有类似 eval 的东西。在运行时对函数进行查找称为“后期绑定”。在 Lisp 中,我们一直在做这些事情。大多数人不知道的:Javascript 基本上是一种具有不同语法的 Lisp 方言。最初设计者想要类似 Scheme 的东西,但不得不改变语法来取悦管理。
标签: programming-languages lisp dynamic-languages