位置: 编程技术 - 正文

javascript SpiderMonkey中的函数序列化如何进行

编辑:rootadmin
在Javascript中,函数可以很容易的被序列化(字符串化),也就是得到函数的源码.但其实这个操作的内部实现(引擎实现)并不是你想象的那么简单.SpiderMonkey中一共使用过两种函数序列化的技术:一种是利用反编译器(decompiler)将函数编译后的字节码反编译成源码字符串,另一种是在将函数编译成字节码之前就把函数源码压缩并存储下来,用到的时候再解压还原. 如何进行函数序列化 在SpiderMonkey中,能将函数序列化的方法或函数有三个:Function.prototype.toString,Function.prototype.toSource,uneval.只有toString方法是标准的,也就是各引擎通用的.但是ES标准中关于Function.prototype.toString方法的规定(ES5 .3.4.2)只有寥寥数语,也就是说,基本没有标准,引擎自己决定该如何实现. 函数序列化的作用 函数序列化最主要的作用应该是利用序列化生成的函数源码来重新定义这个函数. 你也许会想:"我写了这么多年Javascript,怎么没有遇到这种需求".的确,如果是自己的网站,自己完全控制的js文件,不需要以这种打补丁的方式来修改函数,直接修改就可以了.但是如果源文件不是你能控制的了的话,就很有可能要这样做了.比如常用的地方有greasemonkey脚本:你可能需要禁用或修改某个网站中的某个函数.还有就是Firefox扩展:你需要修改Firefox自身的某个函数(可以说Firefox是用JS写的).举个我自己写的Firefox脚本的例子: 这个代码的作用是:在地址栏上回车时,让Firefox在新标签中打开页面,而不是占用当前标签.实现方式就是用toString方法读取到gURLBar.handleCommand函数的源码,然后用正则替换后传给eval,重新定义了这个函数. 为什么不用直接定义的方式,也就是直接重写函数呢: gURLBar.handleCommand = function(){...//将原本的函数更改了一个小地方} 不能这么做的原因是因为我们得考虑兼容性,我们应该尽可能小的更改这个函数的源码.如果这么写的话,Firefox的gURLBar.handleCommand源码一旦发生变化,这个脚本就失效了.比如Firefox3和Firefox4中都有这个函数,但函数内容差别非常大,可是如果用正则替换部分关键字的话,只要这个被替换的这个关键字没有发生变化的话,就不会出现不兼容的现象. 反编译字节码 在SpiderMonkey中,函数在被解析之后会被编译成字节码(bytecode),也就是说,内存中存储着并不是原始的函数源码.SpiderMonkey中存在一个反编译器,它的主要作用就是把函数的字节码反编译成函数源码的形式. 在Firefox以及之前的版本中,SpiderMonkey使用的就是这种方法,如果你使用的是这些版本的Firefox的话,可以尝试下面的代码: 输出和其他的浏览器完全不同: 1.没有意义的原始值字面量在编译的时候会被删除,这个例子中就是"字符串". 你也许会觉得:"貌似没什么问题,反正这些值对于函数的运行来说并没有什么意义".等等,你是不是忘了个东西,表示严格模式的字符串"use strict"怎么办呢? 在不支持严格模式的版本中,比如Firefox3.6,这个"use strict"和其他字符串没什么区别,编译的时候会被删除.在SpiderMonkey实现了严格模式之后,虽然编译的时候同样会忽略掉这个字符串"use strict",但在反编译的时候会进行判断,如果这个函数处于严格模式中,则会在函数体的第一行添加上"use strict",下面是对应的引擎源码. static JSBool 2.注释在编译的时候也会被删除 这个貌似没太大影响,不过有些人愿意利用函数注释来实现多行字符串,这个方法在Firefox 之前的版本中是不可用的. 我 你 他 3.原始值字面量的运算会在编译时进行. 这算是一种优化方式,《高性能JavaScript》提到过: 反编译的弊端 由于新技术的出现(比如严格模式)以及在修改其他相关bug的时候,反编译器这部分的实现经常需要更改,更改就有可能产生新的bug,我自己就亲身遇到过一个bug.大概是在Firefox左右的时候,具体问题记不大清了,反正是关于反编译时小括号是否要保留的问题,大概是这样的: 在反编译时,(a+b)中的小括号被省略了,由于加法结合律从左到右,所以这没关系.但我遇到的bug是这样的: 这就就不行了,a+b+c不等于a+(b+c),比如在a=1,b=2,c="3"的情况下,a+b+c等于"",而a+(b+c)等于"". 关于反编译器,Mozilla工程师Luke Wagner指出,反编译器对他们实现一些新功能的阻碍很大,而且经常会出现一些bug: Not to pile on, but I too have felt an immense drag from the decompiler in the last year. Testing coverage is also poor and any non-trivial change inevitably produces fuzz bugs.The sooner we remove this drag the sooner we start reaping the benefits. In particular,I think now is a much better time to remove it than after doing significant frontend/bytecode hacking for new language features. Brendan Eich也表示,反编译器的确有很多不理想: I have no love for the decompiler, it has been hacked over for years. 存储函数源码 从Firefox之后,SpiderMonkey改成了第二种实现方法,其他浏览器也应该是这样实现的吧.函数序列化得到的字符串完全和源码一致,包括空白符,注释等等.这样的话,大部分问题就应该没有了吧.不过,貌似我又想到个问题.还是关于严格模式的. 比如: 当然,返回的源码中也应该有"use strict",所有浏览器都是这么实现的: 但如果是这样呢: 内部函数B也处于严格模式中,输出B的函数源码应不应该加上"use strict"呢.试验一下: 上面说了,Firefox之前Firefox4之后的版本是通过判断当前函数是否处于严格模式来决定输出不输出"use strict"的,函数B继承了函数A的严格模式,所以会有"use strict". 同时函数源码是缩进严格的,因为在反编译的时候,SpiderMonkey会给反编译出的源码进行格式化,即使之前的源码完全没有缩进也没关系: Firefox之后的版本会不会带有"use strict"呢?因为是直接把函数源码保存下来的,而且函数B中的确没有"use strict"字样.试验结果是:会添加上"use strict",只是缩进有点问题,因为没有格式化这一步了. SpiderMonkey最新版的jsfun.cpp源码中有对应的注释 // 如果一个函数的某个上层函数中拥有"use strict",那么这个函数就继承了上层函数的严格模式. // 我们也会在这个内部函数的函数体内插入"use strict". // 这就确保了,如果这个函数的toString方法的返回值被重新求值时, // 重新生成的函数会和原函数有着相同的语义. 而不同的是,其他浏览器都是不带"use strict"的: 虽然这不会有什么太大影响,但我觉的Firefox的实现是更合理的.

推荐整理分享javascript SpiderMonkey中的函数序列化如何进行,希望有所帮助,仅作参考,欢迎阅读内容。

javascript SpiderMonkey中的函数序列化如何进行

文章相关热门搜索词:,内容如对您有帮助,希望把文章链接给更多的朋友!

php图像生成函数之间的区别分析 新手对php图像生成函数imagecreatetruecolor()和imagecreate()又不解之处,首先来看看官方对这两个函数的解释:resourceimagecreatetruecolor(int$x_size,int$y_size)返回一

javascrpt绑定事件之匿名函数无法解除绑定问题 经常听到有人说,匿名函数绑定事件不好控制啊,无法解除绑定啊等等等等,一直很奇怪谁说的不能解除绑定。下面来实现click事件2次后,自动解除绑

缓动函数requestAnimationFrame 更好的实现浏览器经动画 写缓动函数用到requestAnimationFrame函数,之前了解过一些,但总觉得又不是很了解,所以翻译一篇老外的文章,以便学习分享。requestAnimationFrame是什么?

标签: javascript SpiderMonkey中的函数序列化如何进行

本文链接地址:https://www.jiuchutong.com/biancheng/379158.html 转载请保留说明!

上一篇:javascript中有趣的反柯里化深入分析(javascript可以制作哪些游戏?)

下一篇:php图像生成函数之间的区别分析(php绘制图形函数)

  • 运输发票税率是9
  • 房屋租赁印花税怎么算
  • 员工福利开的专票怎么做分录
  • 增值税减免附加税怎么申报
  • 银行融资服务费怎么算
  • 计提固定资产折旧,车间使用的固定资产折旧1400
  • 百旺税盘网络连接不上
  • 服务收入属于什么会计要素
  • 固定资产什么时候入账
  • 现金支票提取现金备用
  • 库存商品公司自己用怎么下账
  • 产权转移书据印花税是双方交吗
  • 增值税发票红字发票怎么做凭证
  • 印花税核定表申请
  • 实物型产品的基础知识
  • 已经销售但是没货怎么办
  • 什么情况下从价计征房产税
  • 因改制重组等原因撤回出口退税备案需要提交哪些资料?
  • 社保银行扣款未扣怎么办
  • 固定资产作为投资入股为何体现在资本公积
  • 半成品加工费计入什么科目
  • 不知道哟
  • 继续涉入资产会计处理
  • 广告公司的材料的作用有哪些
  • 同业拆入属于哪个行业
  • PHP:mcrypt_enc_is_block_algorithm()的用法_Mcrypt函数
  • 2021最好的固态
  • 固定资产没有发票可以计提折旧吗
  • 车船税不计提怎么做分录
  • php事务特性
  • thinkphp jquery实现图片上传和预览效果
  • 当月没有生产情况正常吗
  • 承租方的物品如何处理
  • yolov3实现
  • php类的特性实例是什么
  • 销售费用处理不包括哪些
  • 企业的工会经费可以用于什么地方
  • 在计算土地增值税时质量保证金可以扣除
  • 小规模纳税人增值税账务处理
  • 摊销结束后
  • linux db2安装与配置
  • 融资租赁的种类
  • 单位产品税金计算公式
  • 收伙食费入什么科目
  • 工会经费支出实施细则
  • 个体工商户属于个人还是企业
  • 汽车销量多少才能赚钱
  • 企业收入总额是营业额吗
  • 租车协议要不要报税务机关备案?
  • 销售货物提供运输服务分录
  • 管理费用如何冲减
  • 如何判定专利是否侵权
  • 将借款存入银行会计分录
  • 企业什么时候才需要交税
  • 资产负债表和利润表的利润不一致
  • 商品折扣计入哪个科目
  • 药品进销差价科目明细
  • 其他费用包括哪些内容
  • 企业如何建账做账
  • win7系统怎么关闭病毒防护
  • win10 没有用户
  • fedora s9
  • win8系统无法开机如何备份数据
  • WIN10系统中断
  • win10移动版能运行电脑软件吗
  • Win7如何关闭Smartscreen筛选器?Win7关闭Smartscreen筛选器的方法
  • 没有启动界面
  • 安卓注入工具
  • opengl调色
  • 微信小程序wx.request实现后台数据交互功能分析
  • [置顶]JM259194
  • JavaScript Math.ceil() 函数使用介绍
  • python操作xml文件
  • node.js使用教程
  • jquery常用的事件绑定函数有哪些
  • shell for遍历
  • unity鼠标控制物体移动
  • 上海税务开户
  • 南通国资委网站首页
  • 辽宁省医保明细查询
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设