在不支持strict模式的版本中,比如Firefox3.6,这个‘use strict’和其他字符串没什么区别,编译时会被删除。SpiderMonkey实现严格模式后,虽然这个字符串‘use strict’在编译时也会被忽略,但在反编译时会被判断。如果此函数处于严格模式,则“use strict”将被添加到函数体的第一行,如下所示
静态JSBool复制代码如下:反编译Body (JSPrinter * JP,JSScript * Script,JSByteCode * PC) {/*打印一个严格模式代码指令,如果需要的话。*/if(脚本严格的调制解调器代码!jp-strict){ if(jp-fun(jp-fun-flags JSFUN _ EXPR _ CLOSURE)){/* *我们没有严格函数表达式的语法;*至少给个提示。*/js_printf(jp,' \ t/* use strict */\ n ');} else { js_printf(jp,' \ t 'use strict\ n’);} jp-strict=true;}
jsbytecode *end=script-code脚本长度;返回反编译码(jp,script,pc,end - pc,0);}如何进行函数序列化
这看起来影响不大,但是有人愿意用函数注释来实现多行字符串。该方法在Firefox 17之前的版本中不可用。复制代码如下:函数heredoc (f) {return f.tostring()。替换(/。\ s/,' ')。替换(/。$/,'');} var string=heredoc(function(){/* I you he */});console . log(string)I you he函数序列化的作用。
这是一种优化方法,《高性能JavaScript》:Firefox脚本的例子中提到过。由于新技术的出现(如严格模式)和其他相关bug的修改,这部分反编译程序的实现往往需要更改,而更改可能会导致新的bug。我自己也遇到了一个bug。大概在Firefox10左右,具体问题记不太清楚了。反正就是反编译的时候括号要不要保留的问题。大概是这样的:复制代码如下:(function (a,b,c) {return (a b) c})。Tostring ()' function (a,b,c){ return a b c;} '反编译时,(a b)中的括号被省略了,所以没关系,因为加法和连词的规律是从左到右的。但是我遇到的bug是这样的:复制代码如下:(function (a,b,c) {return a (b c)})。tostring()'函数(a,b,c)。} '这个不行。a b c不等于a (b c)。比如在A=1,B=2,C=' 3 '的情况下,a b c等于' 33 ',a (b c)等于' 123 '。
关于反编译程序,Mozilla工程师Luke Wagner指出,反编译程序是他们实现一些新功能的一大障碍,并且经常出现一些bug:
不要添油加醋,但去年我也感受到了反编译器的巨大阻力。测试覆盖率也很低,任何不重要的变化都不可避免地会产生模糊的错误。我们越早摆脱这一拖累,就能越早开始获益。特别是,我认为现在是移除它的最佳时机,而不是在为新的语言特性进行大量前端/字节码攻击之后。
Brendan Eich还说,反编译器确实有许多缺点:
我不喜欢反编译程序,它已经被破解了17年。在Firefox17之后,SpiderMonkey被改成了第二种实现方法。其他浏览器也应该这样做。函数序列化得到的字符串与源代码完全一致,包括空格、注释等。这样的话,大部分问题应该都没有了。不过,好像我还有一个问题。还是关于严格模式的。
比如复制代码如下:(函数A(){ ' use strict ';alert(' A ');})“”当然,返回的源代码中也应该有‘use strict’。所有浏览器都是这样实现的:复制代码代码如下:function A(){ ' use strict ';alert(' A ');}但如果是呢:复制代码code如下:(function A(){ ' use strict ';函数B () {alert ('b')}}()' '内部函数B也处于严格模式。输出B的函数源代码要加‘use strict’吗?尝试一下:
如前所述,Firefox17之前的Firefox4之后的版本通过判断当前函数是否处于严格模式来决定是否输出‘使用严格’。函数B继承了函数A的严格模式,所以会有‘使用严格’。
同时,函数源代码是严格缩进的,因为在反编译过程中,SpiderMonkey会对反编译后的源代码进行格式化,即使之前的源代码根本没有缩进。复制的代码代码如下:函数B(){ ' use strict ';alert(' B ');}火狐17之后的版本会不会自带‘使用严格’?因为函数的源代码是直接保存的,而函数b中不存在' use strict '这个词,实验结果是会添加' use strict ',但是有一个缩进的问题,因为没有格式化的步骤。复制代码如下:函数B(){ ' use strict ';
Alert ('b')}最新版本的SpiderMonkey在jsfun.cpp源代码中有相应的注释。
//如果函数的某个上层函数中有“use strict ”,则该函数继承上层函数的严格模式。//我们还会在这个内部函数的函数体中插入‘use strict’。//这确保了如果重新计算这个函数的toString方法的返回值,//重新生成的函数将具有与原始函数相同的语义。
不同的是其他浏览器没有' use strict ':复制代码如下:function B() {alert('B')}虽然这个不会有太大影响,但我觉得Firefox的实现更合理。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。