eval函数是动态生成代码的一种强大而简单的方法,那么需要注意的是什么?
- Simon Willison-24ways.org/2005/Dont-Be-Eval的Don't Be Eval()。
- 正如moduscreate.com/javascript-performance-tips-tricks(new function(str))(新函数(str)))中所述,与eval(str)相比,它的性能更高。只是我的2美分:)
- 显然,新的fcunton(a)比铬合金的eval(a)慢67%。
- 对于我来说,新功能(A)比OSX上最新的Chrome慢80%。
- 我添加了一个静态函数,只是为了比较性能。jspef.com/eval-vs-new-function/2
- 与PHP中的include和require相同的警告。eval也可以称为"include-from-u-string"或"runtime-compile"。它不仅不邪恶,而且我确信它是创建脚本的基本原因之一——比起每次需要更改时都重新编译一个dll,让一个脚本在不重新编译的情况下对一个对象进行eval并开始使用它/更改它要容易得多。从高层的角度来看,eval与将C文件编译为dll,然后调用其"入口点",并链接到其"状态符号"(或让入口点返回状态对象)相同。
不正确使用eval会打开注入攻击代码
调试可能更具挑战性(无行号等)
eval'd代码执行速度较慢(没有机会编译/缓存eval'd代码)
编辑:正如@jeff walden在评论中指出的那样,3今天比2008年更不真实。但是,虽然可能会发生编译脚本的某些缓存,但这将仅限于eval不做任何修改而重复的脚本。更可能的情况是,您正在评估的脚本每次都进行了轻微的修改,因此无法缓存。让我们假设一些eval'd代码执行得更慢。
- @杰夫瓦尔登,评论很好。我已经更新了我的帖子,尽管我知道你已经发了一年了。XNZO72,如果你对你的评论有些保留(就像杰夫那样),那么我可能会同意你的看法。杰夫指出,关键是:"同一字符串多次的eval可以避免解析开销"。事实上,你错了,3适用于许多情况。
- @prestaul:既然假定攻击者可以使用任何开发人员工具来更改客户端中的javascript,为什么要说eval()打开代码以进行注入攻击?尚未打开?(当然,我是在说客户端javascript)
- @Eduardomolteni,我们不关心(实际上不能阻止)用户在自己的浏览器中执行JS。我们试图避免的攻击是保存用户提供的值,然后将其放入javascript和eval'd中。例如,我可以将用户名设置为:badHackerGuy'); doMaliciousThings();,如果您使用我的用户名,将其合并到某个脚本中并在其他人的浏览器中对其进行eval,那么我可以在他们的计算机上运行任何我想要的javascript(例如,强制他们使用+1我的帖子,将他们的数据发布到我的服务器等)
- afaik、google chrome&chromium dev工具可以像调试其他JS文件一样调试评估代码。但是您不能放置断点。
- 一般来说,1在很多情况下都是正确的,如果不是大多数函数调用的话。eval()不应该仅仅因为缺乏经验的程序员滥用它而被经验丰富的程序员单独挑选和避免。然而,经验丰富的程序员在他们的代码中通常有一个更好的体系结构,并且由于这个更好的体系结构,eval()将很少被需要或考虑。
- @弗罗德博里,我不同意你的开场白。eval与函数调用有根本不同。请阅读我对Eduardomolteni的评论(上面2条)以获得解释。注入攻击特别指接受用户输入并允许它在自己浏览器之外的其他地方执行。(例如服务器或其他用户的浏览器)但是,我同意如果您很好地设计应用程序,那么很少需要eval。应该避免这样做,因为几乎总是有一个更好、更安全的解决方案。
- @Tamilvendhan确定可以放置断点。您可以通过在源代码中添加debugger;语句来访问chrome为evaled编码创建的虚拟文件。这将停止在该行上执行程序。然后,您可以像添加另一个JS文件一样添加调试断点。
- 谢谢您。这个简洁的答案告诉我,我可以在我当前的任务/上下文中使用eval。有很多不明确的建议就是不要使用它。
- @你的第二句话也是错误的。许多经验丰富的程序员/框架仍然大量使用evil()。以SAP OpenUI5为例。
- @在使用eval()之前,请仔细考虑!有更严格的顾客服务提供商,防止你使用eval()。以Firefox OS为例。
- @安德烈费德勒,我的话都不对。如果你愿意,你可能不同意。任何功能都可以用任何图灵完整语言实现。只有少数语言有eval,因此eval是不需要的——它只是一种方便。eval是函数调用还是语言构造是完全不同的问题。
- @弗罗德博里是的,这是不需要的,但我的声明是关于experienced programmers often have a better architecture in their code。不像你想的那么频繁。;)
- @安德烈费德勒经验丰富的程序员可能代码不好。我们可以达成一致。:)但是我想说的是,一组经验丰富的程序员通常比他们没有经验的时候拥有更好的体系结构。
- Webpack会和你争论的:)
- eval也不坏。我在我的Epic Random String Generator中使用它,它工作得很好!
- 如果您每次执行不同的代码,那么编译和缓存将没有任何好处,不管您是否在使用eval。
- (1)这与要求/包括有什么不同?如果您需要包含外部代码/用户代码,为什么这甚至是一个问题?(2)现代的JavaScript引擎可以告诉您评估代码中错误的确切行和偏移量,就好像您是从anonymouscope.js运行代码一样。(3)这与任何类型的编译过程有什么不同?我认为,使用eval有条件地生成一个函数通常比编写一个有条件的函数要快,或者在多次调用生成的函数时使用全局变量(如手动内联)要快。
- @dmitry,我将只介绍1&2:最大的区别是,如果您使用eval,那么您是以编程方式生成代码的,人们这样做的最常见原因是将用户提供的信息(或代码)注入代码中。这从根本上来说是不安全的,因为它不必要地打开代码来进行注入攻击。如果您正在使用代码生成进行优化,那么可能有一种合法的使用,但这当然是少数使用案例。
- eval最常见的用途是实现"需要"功能,而无需发明新的解析器。另外,我不确定您是否知道什么是注入攻击,但是在客户端,除了函数局部变量之外,您不能避免注入,而且IIFE局部变量除了内存编辑器之外,其他任何对象都不能接触。在服务器端,您需要小心让谁执行任意代码,但即使在那里,它仍然用于实现需求和作为shell替代方案。
- @Dmitry,我认为你从根本上误解了注入攻击…用户在客户端查看自己的内容时,不存在注入的威胁。我们关注的是XSS,这与从另一个用户注入恶意内容有关,从而使他们能够访问另一个用户登录的页面。有一些方法可以避免这种情况,但如果使用eval,则完全取决于开发人员的知识和勤奋。如果需要,只需使用正确的lib。参见:codereview.stackexchange.com/questions/25901/…
- @XSS中的prestaul eval是危险的,但可以通过在函数内部的局部变量中隐藏重要数据以及在从外部域加载文本的eval之前进行凭据测试来缓解。例如,您可以JSON解析要eval的请求,并在对其代码属性进行eval之前检查对象凭据,而不是对代码进行eval。也就是说,我无法想象需要逃避XSS。
埃瓦尔并不总是邪恶的。有时它是完全合适的。
然而,目前和历史上,eval被不知道自己在做什么的人过度使用。不幸的是,这包括编写JavaScript教程的人员,在某些情况下,这确实会带来安全后果——或者更常见的是,简单的错误。因此,我们越能在eval上面加上问号,效果越好。任何时候你使用疏散车,你都需要保持清醒,检查你在做什么,因为很有可能你会用更好、更安全、更清洁的方式。
为了给出一个非常典型的例子,设置一个ID存储在变量"potato"中的元素的颜色:
1
| eval('document.' + potato + '.style.color ="red"'); |
如果上面这类代码的作者对javascript对象的工作原理有了一些线索,他们就会意识到可以使用方括号而不是文字点名,这样就不需要进行eval了:
1
| document[potato].style.color = 'red'; |
号
…更容易阅读,也不太可能有问题。
(但是,如果有人/真的/知道他们在做什么,他会说:
1
| document.getElementById(potato).style.color = 'red'; |
这比直接从文档对象访问dom元素这一老掉牙的技巧更可靠。)
- 嗯,我在第一次学习javascript的时候就走运了。我总是用"document.getElementByID"来访问DOM;讽刺的是,当时我只做了这个操作,因为我不知道对象在javascript中是如何工作的;-)
- 同意。有时候Eval是可以的,例如对于来自WebServices的JSON响应
- @Schoetbi:你不应该用JSON.parse()代替eval()来处理json吗?
- @尼乌斯齐卡7H:你可以的时候,当然。仍然有一些现存的浏览器没有它,唉。
- @bobine code.google.com/p/js on-sans-eval适用于所有浏览器,github.com/douglascorkford/json-js也适用于所有浏览器。DougCrockford的json2.js确实在内部使用eval,但带有检查功能。此外,它还与内置的JSON浏览器支持向前兼容。
- 当然,如果您愿意,可以使用库。但是所有浏览器都必须下载库代码,即使它们有本机支持,所以永远不会使用它。对于我确信JSON是安全的,并且作为JS文本和JSON一样有效的情况,我更愿意为eval节省额外的容量和丰满度。
- @Bobince有一种称为功能检测和polyfill的东西来处理丢失的JSON库和其他东西(请查看modernizer.com)
- "埃瓦尔并不总是邪恶的。"不是吗?我不知道任何情况下,eval是最好的选择。fwiw您可以使用Function构造函数(developer.mozilla.org/en-us/docs/web/javascript/reference/…)实现许多相同的功能,这稍微不那么邪恶。
我相信这是因为它可以从字符串中执行任何javascript函数。使用它使人们更容易将恶意代码注入应用程序。
- 那么还有什么选择呢?
- 实际上,另一种选择就是编写不需要的代码。Crockford详细介绍了这一点,如果您需要使用它,他几乎说这是一个程序设计缺陷,需要重新编写。事实上,我也同意他。尽管JS有很多缺点,但它确实很灵活,并且允许很大的空间使其灵活。
- 但是,当您通过Ajax从服务器获得响应时,您将得到响应文本xmlhttp.response text,并且需要使用eval来执行它。
- 不是这样的,大多数框架都有解析JSON的方法,如果不使用框架,则可以使用json.parse()。大多数浏览器都支持它,如果您真的遇到困难,可以非常容易地为JSON编写一个解析器。
- 我不相信这个论点,因为它已经很容易将流氓代码注入到JavaScript应用程序中。我们有浏览器控制台、脚本扩展等…发送到客户机的每一段代码都是可选的,客户机可以执行。
- 关键是我更容易将代码注入到您的浏览器中。假设您正在对查询字符串使用eval。如果我欺骗你点击一个链接,我的查询字符串连接到该站点,我现在已经在你的机器上执行我的代码,完全有权限从浏览器。我想把你在那个网站上键入的所有内容都输入日志并发送给我?完成了,没有办法阻止我,因为当eval执行时,浏览器给予它最高的权限。
- 我将它用于从服务器发送公式的动态公式处理。这里没有安全风险,唯一的选择是编写一个大型的javascript函数来解构公式。
- @那么,Kevin,在没有eval的情况下,如何在ecmascript 6(es6)支持上提供检测功能呢?还是Crockford建议完全避开ES6?
- @然后,nuander将大函数作为一个单独的.js文件提供服务,并通过在文档中附加一个脚本元素来包含它。
- @Damianyerrick在某些功能检测中不可能不使用它。在那个时候,我会质疑ES6是否真的值得在那个场景中实现。如果必须进行功能检测以查看是否可以使用它,这意味着您必须考虑无法使用的情况。这实际上意味着您必须编写两次代码(一次在ES5中,一次在ES6中)。我只需要继续使用ES5,或者用typescript等语言编写代码,这样当我不再需要支持5时,就可以使用ES6了。
- 为什么会有人评估查询字符串?现在你甚至不需要发布,更不用说获取了,因为有WebSockets。而且,您可以对iframe进行沙盒处理,或者使用Web工作者,其中只有"消息"在两者之间进行通信,并且彼此的命名空间没有访问权限。
我想到两点:
安全性(但只要您自己生成要评估的字符串,这可能不是问题)
性能:在要执行的代码未知之前,无法对其进行优化。(关于javascript和性能,当然是Steve Yegge的演示)
- 如果客户可以用我们的代码做他/她想要的任何事情,为什么安全是一个问题?油脂猴?
- @Paulbrewczynski,当用户A将其部分代码保存为eval时,就会出现安全问题,然后,该小代码在用户B浏览器上运行。
将用户输入传递给eval()是一个安全风险,但每次调用eval()都会创建一个新的javascript解释器实例。这可能是一种资源占用。
- 在我回答这个问题的三年多时间里,我对所发生的事情的理解加深了。实际发生的是创建了一个新的执行上下文。见dmitrysoshnikov.com/ecmascript/chapter-1-execution-contexts
一般来说,只有通过eval用户输入时才会出现问题。
主要是,维护和调试要困难得多。它就像一个goto。你可以使用它,但是它会让你更难发现问题,也会让那些以后需要改变的人更难找到问题。
- eval可以用来替换缺失的元编程特性,比如模板。我更喜欢紧凑的生成器方式,而不是无休止的函数列表。
要记住的一点是,您可以经常使用eval()在其他受限的环境中执行代码-有时在eval块中分解特定的javascript函数会愚弄那些阻止特定javascript函数的社交网站。-
1
| eval('al' + 'er' + 't(\'' + 'hi there!' + '\')'); |
。
所以,如果你想运行一些原本不允许的javascript代码(myspace,我在看你…),那么eval()是一个很有用的技巧。
但是,由于上述所有原因,您不应该将其用于您自己的代码,因为您完全可以控制这些代码——这是不必要的,最好将其放在"棘手的javascript黑客"工具架上。
- 窗口["al"+"er"+"t"]("这也是一个技巧吗?")
- 只是更新上面的代码。--你好!--需要用引号括起来,因为它是一个字符串。eval('al'+'er'+'t('+''你好!'+')');
- 埃多克斯1〔3〕
- 有社交网站限制alert(),但允许eval()?!
除非让eval()成为动态内容(通过cgi或input),否则它与页面中的所有其他javascript一样安全可靠。
- 虽然这是真的——如果你的内容不是动态的,那么有什么理由使用eval呢?你可以把代码放在一个函数中,然后调用它!
- 例如,解析来自Ajax调用的返回值(类似于JSON、服务器定义的字符串等)。
- 哦,我明白了。我之所以称之为动态,是因为客户不知道它们是什么,但我现在明白了你的意思。
除了其他答案,我不认为eval语句可以高级最小化。
这是一个可能的安全风险,它有不同的执行范围,而且效率非常低,因为它为代码的执行创建了一个全新的脚本环境。有关更多信息,请参阅此处:eval。
但是,它非常有用,并且与适度一起使用可以添加很多好的功能。
除非您100%确信正在评估的代码来自可信的源(通常是您自己的应用程序),否则这是一种将系统暴露于跨站点脚本攻击的可靠方法。
- 只有在服务器端安全性不好的情况下。客户端的安全性简直是胡说八道。
如果你知道在什么环境中使用它,就不一定那么糟糕。
如果您的应用程序正在使用eval()从某个JSON创建一个对象,该JSON已从xmlhttpRequest返回到您自己的站点,由受信任的服务器端代码创建,那么这可能不是问题。
不受信任的客户端JavaScript代码无论如何也不能做到这一点。如果你正在执行的eval()源于一个合理的来源,你就可以了。
- 使用eval是否比解析JSON慢?
- 是的。很多。
- @在我的浏览器(Chrome53)上运行该测试会显示eval比parse快一些。
- @Peratabretta啊,奇怪。我想知道为什么。当时我说不是这样的。然而,对于Chrome来说,从一个版本到另一个版本,在运行时的某些区域获得奇怪的性能提升并非闻所未闻。
- 这里有一个小的旧线程,但是根据我读到的内容——不是说我自己追踪到的——json.parse实际上是eval的,它是最后阶段的输入。因此,效率方面,需要更多的工作/时间。但是安全方面,为什么不直接解析呢?eval是一个很棒的工具。把它用在没有其他方法的东西上。要通过JSON传递函数,有一种不使用eval的方法。在json.stringify中的第二个参数允许您放置一个回调来运行,您可以通过typeof检查它是否是一个函数。然后获取函数的.ToString()。如果你搜索的话,这里有一些很好的文章。
我知道这个讨论已经过时了,但我真的很喜欢Google的这种方法,我想和其他人分享这种感觉;)
另一件事是,你越能理解,你就越能理解,最后你只是不相信某件事是好是坏,只是因为有人这么说:)这是一个非常鼓舞人心的视频,它帮助我自己思考更多:)好的实践是好的,但不要盲目地使用它们:)
- 对。到目前为止,至少在Chrome中,我发现了一个更有效的用例。运行一个raf,在每次迭代中对给定变量中的字符串进行求值。使用setInterval只设置字符串中图形化的内容,如设置转换等。我尝试过许多其他的方法,比如循环数组中的函数,或者使用变量仅为已更改的元素设置转换,但到目前为止,这似乎是最有效的方法。当涉及到动画时,最真实的测试是你的眼睛。
如果您希望用户输入一些逻辑函数并对其进行评估,那么javascript eval函数是完美的。我可以接受两个字符串和eval(uate) string1 === string2等。
它大大降低了你对安全的信心。
如果在代码中发现eval()的用法,请记住"eval()是邪恶的"这句咒语。
这个函数接受任意字符串并将其作为JavaScript代码执行。当代码在问题是预先知道的(在运行时不确定),没有理由使用eval()。如果代码是在运行时动态生成的,通常有更好的方法在不使用eval()的情况下实现目标。例如,只需使用方括号符号访问动态属性更好、更简单:
1 2 3 4 5 6 7
| // antipattern
var property ="name";
alert(eval("obj." + property));
// preferred
var property ="name";
alert(obj[property]); |
使用eval()也会带来安全隐患,因为您可能正在执行代码(用于来自网络的示例)已被篡改。当处理来自Ajax请求的JSON响应时,这是一个常见的反模式。在那些情况下最好使用浏览器的内置方法来解析JSON响应以使当然安全有效。对于本机不支持JSON.parse()的浏览器,您可以使用json.org中的库。
同样重要的是要记住,向setInterval()和setTimeout()传递字符串,而Function()构造函数在很大程度上与使用eval()相似,因此应该避免。
在幕后,javascript仍然需要评估和执行作为编程代码传递的字符串:
1 2 3 4 5 6 7 8 9
| // antipatterns
setTimeout("myFunc()", 1000);
setTimeout("myFunc(1, 2, 3)", 1000);
// preferred
setTimeout(myFunc, 1000);
setTimeout(function () {
myFunc(1, 2, 3);
}, 1000); |
号
使用新的函数()构造函数与eval()类似,应该接近它小心点。它可能是一个强大的结构,但经常被误用。如果你必须的话使用eval(),可以考虑改用new函数()。
潜力很小好处是,在new函数()中计算的代码将在本地函数中运行作用域,因此在被评估的代码中用var定义的任何变量都不会变为全局自动。
另一种防止自动全局调用的方法是eval()调用立即函数。
- 你能建议我如何在不使用eval的情况下计算函数局部动态变量名吗?在大多数语言中,eval(和类似的)函数是最后的手段,但有时是必要的。在获取动态变量名的情况下,是否有更安全的解决方案?在任何情况下,JavaScript本身都不是为了真正的安全(显然服务器端是主要的防御)。如果您感兴趣,这里是我的eval用例,我想修改一下:stackoverflow.com/a/48294208
这是一篇很好的文章,讲的是eval,以及它如何不是一种邪恶:http://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misshood/
I’m not saying you should go run out and start using eval()
everywhere. In fact, there are very few good use cases for running
eval() at all. There are definitely concerns with code clarity,
debugability, and certainly performance that should not be overlooked.
But you shouldn’t be afraid to use it when you have a case where
eval() makes sense. Try not using it first, but don’t let anyone scare
you into thinking your code is more fragile or less secure when eval()
is used appropriately.
号
eval()非常强大,可以用于执行JS语句或计算表达式。但问题不在于eval()的使用,而在于您使用eval()运行的字符串如何受到恶意方的影响。最后,您将运行恶意代码。有了权力,责任就大了。所以明智地使用它就是你在使用它。这与eval()函数没有太多关系,但本文提供了非常好的信息:http://blogs.popart.com/2009/07/javascript-injection-attacks/如果要查找eval()的基础知识,请查看以下内容:https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/eval
随着下一代浏览器推出某种风格的JavaScript编译器,这可能成为一个更大的问题。通过eval执行的代码在这些新浏览器上的性能可能不如其他的javascript。有人应该做一些分析。
除了在执行用户提交的代码时可能出现的安全问题之外,大多数情况下还有一种更好的方法,不需要每次执行代码时都重新解析代码。匿名函数或对象属性可以替代eval的大部分用途,并且更安全、更快。
我想说的是,如果您在浏览器中运行的javascript中使用eval(),这并不重要。*(警告)
所有的现代浏览器都有一个开发人员控制台,您可以在那里执行任意的javascript,任何半智能的开发人员都可以查看您的JS源代码,并将他们需要的任何部分放入开发人员控制台中,以执行他们想要的操作。
*只要您的服务器端点对用户提供的值进行了正确的验证和消毒,那么在客户端JavaScript中解析和评估什么就不重要了。
但是,如果您要询问是否适合在PHP中使用eval(),答案是否定的,除非您将可能传递给eval语句的任何值白列出来。
- 不仅有一个dev控制台,您还可以在url栏中键入javascript:code来在页面上构建自己的dev控制台(如果没有),就像在旧的IE浏览器和移动设备上一样。
我不会试图反驳之前所说的任何事情,但我会提供eval()的这种用法(据我所知),这种用法不能以任何其他方式进行。可能还有其他的方法来编写代码,也可能有一些方法来优化它,但是为了清晰起见,这是一个很长的过程,而且没有任何提示和口哨,以说明eval的使用实际上没有任何其他的选择。即:动态(或更准确地说)编程创建的对象名(而不是值)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| //Place this in a common/global JS lib:
var NS = function(namespace){
var namespaceParts = String(namespace).split(".");
var namespaceToTest ="";
for(var i = 0; i < namespaceParts.length; i++){
if(i === 0){
namespaceToTest = namespaceParts[i];
}
else{
namespaceToTest = namespaceToTest +"." + namespaceParts[i];
}
if(eval('typeof ' + namespaceToTest) ==="undefined"){
eval(namespaceToTest + ' = {}');
}
}
return eval(namespace);
}
//Then, use this in your class definition libs:
NS('Root.Namespace').Class = function(settings){
//Class constructor code here
}
//some generic method:
Root.Namespace.Class.prototype.Method = function(args){
//Code goes here
//this.MyOtherMethod("foo")); // =>"foo"
return true;
}
//Then, in your applications, use this to instantiate an instance of your class:
var anInstanceOfClass = new Root.Namespace.Class(settings); |
编辑:顺便说一句,我不建议(出于之前指出的所有安全原因)将对象名建立在用户输入的基础上。不过,我想不出有什么好理由让你这么做。不过,我想我会指出这不是个好主意:)
- 这可以用namespaceToTest[namespaceParts[i]]完成,这里不需要eval,所以if(typeof namespaceToTest[namespaceParts[i]] === 'undefined') { namespaceToTest[namespaceParts[i]] = {};是else namespaceToTest = namespaceToTest[namespaceParts[i]];的唯一区别。
javascript引擎在编译阶段执行了许多性能优化。其中一些归根结底就是能够在代码执行时对其进行静态分析,并预先确定所有变量和函数声明的位置,这样在执行期间解析标识符的工作就更少了。
但是,如果引擎在代码中发现一个eval(..),那么它本质上必须假定它对标识符位置的所有感知都可能是无效的,因为它无法在词法转换时准确地知道可以传递给eval(..)以修改词法作用域的代码,或者传递给它的对象的内容,从而创建一个新的要查询的词法作用域。
换句话说,在悲观的意义上,如果存在eval(..)的话,它所做的大多数优化都是毫无意义的,因此它根本就不执行优化。
这就解释了一切。
参考文献:
https://github.com/getify/you dont know js/blob/master/scope%20&;%20闭包/ch2.md eval
https://github.com/getify/you dont know js/blob/master/scope%20&;%20闭包/ch2.md性能
- 没有一个javascript引擎不能在100%保证的代码中找到和评估。因此,它必须随时准备好。
这并不总是个坏主意。例如,代码生成。我最近写了一个名为超链接的库,它弥合了虚拟DOM和把手之间的鸿沟。它通过解析一个手柄模板并将其转换为随后由虚拟DOM使用的超脚本来实现这一点。超脚本首先作为字符串生成,在返回它之前,eval()将其转换为可执行代码。我发现在这种情况下,以东十一〔0〕与邪恶完全相反。
基本上来自
1 2 3
| {{#each names}}
<span>{{this}}</span>
{{/each}} |
号
为了这个
1 2 3 4 5 6 7
| (function (state) {
var Runtime = Hyperbars.Runtime;
var context = state;
return h('div', {}, [Runtime.each(context['names'], context, function (context, parent, options) {
return [h('span', {}, [options['@index'], context])]
})])
}.bind({})) |
在这种情况下,eval()的性能不是问题,因为您只需要解释生成的字符串一次,然后多次重复使用可执行输出。
如果您好奇的话,可以看到代码生成是如何实现的。