Hanjst模板语言和模板引擎,近期不断完善升级。本次改进主要是为了增加安全输出表达式的兼容性。由于涉及到软件开发过程中的效率和软件运行效率之间的平衡和权衡,所以我多写了几句来描述这个权衡的思考过程。自从上次更新:?Hanjst升级:+showImageAsync和性能提升等(https://ufqi.com/blog/hanjst-...),时间并没有过去太久,希望Hanjst早日成熟稳定。一、问题及背景Hanjst模板语言解析引擎是用JavaScript严格模式(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode)编写的,能够执行程序语句严格的语法检查,所以如果写的不严格,偶尔会抛出异常错误警告。之所以提出这个要求,严格模式使用JavaScript,是希望Hanjst可以用在一些关键领域和要求高的岗位上,杜绝编程阶段的异常错误。允许异常在“编译时”发生然后解决是一种编程语言对齐的编译类型。这是好事,因为Hanjst不仅用在普通的资讯网站,还用在电子商务、金融等领域。对其进行严格的语法检查是必要的步骤。不过这也有缺点,就是开发起来比较费时,需要考虑各种情况,反复测试软件在各种场景下的行为,无意中会增加开发成本。比如严格模式下的常见错误:undefinedvariablesandaccessobjectsareundefined。错误信息在Hanjst中有更友好的显示和输出,参考:Hanjst+更新升级:报错、innerLoop和loadingLayer,https://ufqi.com/blog/hanjst-...。如果对接系统处于非关键领域和要求较高的位置,是否可以对未定义的变量或重复出现的未定义对象的访问进行一些主动兼容?这次就是调查这个问题。2、解决思路和方法排查这个问题大致有两种方法:1)在编译模板的时候,去掉javascript对strict模式,让它不再进行严格检查,避免类似undefined变量和访问undefined对象;2)第二种思路是在保持严格模式正确的前提下,做一些局部微调,使其能够兼容这些低级错误,同时也对其他文法对保持严格检查。去除大方向的Strict模式显然是不可能的,这会从本质上动摇Hanjst在关键领域和高要求位置的定位。这不应该被讨论。为编译时语法检查启用严格模式,这对于严肃的软件是必需的。在JavaScript中,很容易检测一个变量是否被定义。使用一对类似于typeof的指令,你可以判断一个变量是否被定义。如果在输出前对每个变量都做这样的检查,显然陷入了“一个人有病,全国吃药?”的非理性状态。这也是之前的尝试被阻止的原因之一。所以如果你想启用变量检测,需要有一些机制来检测已经定义的变量。另外,如果不使用JavaScript的eval等高危函数,如何感知某个字符串表示的变量是否被定义?使用内置对象Function构建匿名函数?如果存在匿名函数,其单独的变量作用域与变量的实际运行环境有明显差异,怎么办?第三,在模板语言中,我们允许访问对象的属性。这些对象可能是运行时环境中的全局变量,也可能是局部变量;这样的对象可能是一维的Hash数据列表,也可能是多位的Hash嵌套,第一维可能有数据对象已经定义,而第二维和第三维是未定义的,如果未定义这时候可能会抛出异常。需要进一步发散的问题是:1)继续启用Strict模式,2)在1)的情况下实现对未定义变量和未定义对象访问的兼容;3)尽量不要使用高危函数,比如eval;4)保证2)在所有情况下,不可能不顾一切地对所有变量进行兼容操作;5)需要区分是全局变量还是局部变量,最好在所有情况下都兼容;6)需要区分一维对象和多维对象。所有情况都是最好的兼容。经过一番艰难的摸索,在两全其美的情况下,采取以下措施:1)使用typeof生成一条JavaScript语句,表明要执行的变量是否定义;2)增加环境变量赋值语句列表,检测变量是否被显式定义;3)使用window.hasOwnProperty检测是否定义了一个全局变量;4)递归分解多维数据对象,例如$aList[$ak1][$ak2][$ak3]。基于以上分析,在Hanjst.js中新增了_enSafeExpression函数,用于检查输出的变量和对象的安全性。3.实例演示{$a=1}–>类似的语句被注册为变量已经显式声明;{\$a}–>((typeof$a=='undefined')?”:\$a),输出$apair语句如果检测到没有定义,则改写为表达式三元运算符的;$aList[$ak1][$ak2][$ak3]–>$aList[$ak1],$aList[$ak1][$ak2],将三维数据拆解为逐层输出,形成两个待检测的变量/对象,然后分别构造三元运算符的表达式,形成自上而下的逐层检测,大致为:((typeof$aList[$ak1]=='undefined')?”:((typeof$aList[$ak1][$ak2]=='undefined')?”:$aList[$ak1][$ak2][$ak3]))更多维度的数据对象,等等。4.其他版本号升级到v1.7,+其他一些小的优化调整,一个简单的问题一点都不简单,一点都不简单。一个小任务,变量输出前的主动安全检查,居然写了差不多2000字。毕竟汉杰斯特追求的是平衡的艺术,追求的是极致和完美。….?HanjstHanjst是一个基于JavaScript的模板语言和模板解析引擎,她运行在客户端或服务器端。?HanjstHanjst可以表达逻辑控制,可以实现和服务器端模板语言一样强大的功能。当Hanjst完全在客户端解析时,节省了服务器端的计算资源;Hanjst模板语言是独立的,不绑定任何服务端资源;纯MVC,层间数据以JSON格式传输;全面支持常用的模板语言功能,具有复杂而强大的JavaScript编程能力;无学习成本,直接使用JavaScript编写模板语言;....Hanjst是一种基于JavaScript的模板语言和解析引擎,同时运行在客户端和/或服务器端。Hanjst可以表达逻辑控制并实现相同的功能作为服务器端模板语言。Hanjst在客户端的运行时,减少服务器端的计算渲染;Hanjst是语言无关的,不受后端脚本或语言的约束;与MVC、数据传输完全隔离withJSON;全支持模板标签,内置逻辑和自定义JavaScript函数;不用再学标签语言,只需要学习JavaScript;……这两天连续创建了两篇文章,正在写写博客也是历史上罕见的行为。同期写的另一篇文章:写?存款利率贷款利率和负利率,https://ufqi.com/blog/captial...。http://ufqi.com/blog/hanjst-ensafeexpr-updt/-R/x12SXhttps://ufqi.com/news/list.932.html
