深入理解JavaScript系列(2):揭秘命名函数表达式(7)

来源:未知 责任编辑:责任编辑 发表时间:2014-01-26 22:00 点击:

  IE6:    without `null`:   7.6K -> 20.3K    with `null`:      7.6K -> 18K  IE7:    without `null`:   14K -> 29.7K    with `null`:      14K -> 27K复制代码
如我们所料,显示断开引用可以释放内存,但是释放的内存不是很多,10000个函数对象才释放大约3M的内存,这对一些小型脚本不算什么,但对于大型程序,或者长时间运行在低内存的设备里的时候,这是非常有必要的。

 

关于在Safari 2.x中JS的解析也有一些bug,但介于版本比较低,所以我们在这里就不介绍了,大家如果想看的话,请仔细查看英文资料。

SpiderMonkey的怪癖
大家都知道,命名函数表达式的标识符只在函数的局部作用域中有效。但包含这个标识符的局部作用域又是什么样子的吗?其实非常简单。在命名函数表达式被求值时,会创建一个特殊的对象,该对象的唯一目的就是保存一个属性,而这个属性的名字对应着函数标识符,属性的值对应着那个函数。这个对象会被注入到当前作用域链的前端。然后,被“扩展”的作用域链又被用于初始化函数。

在这里,有一点十分有意思,那就是ECMA-262定义这个(保存函数标识符的)“特殊”对象的方式。标准说“像调用new Object()表达式那样”创建这个对象。如果从字面上来理解这句话,那么这个对象就应该是全局Object的一个实例。然而,只有一个实现是按照标准字面上的要求这么做的,这个实现就是SpiderMonkey。因此,在SpiderMonkey中,扩展Object.prototype有可能会干扰函数的局部作用域:

  Object.prototype.x = 'outer';    (function(){        var x = 'inner';        /*      函数foo的作用域链中有一个特殊的对象——用于保存函数的标识符。这个特殊的对象实际上就是{ foo: <function object> }。      当通过作用域链解析x时,首先解析的是foo的局部环境。如果没有找到x,则继续搜索作用域链中的下一个对象。下一个对象      就是保存函数标识符的那个对象——{ foo: <function object> },由于该对象继承自Object.prototype,所以在此可以找到x。      而这个x的值也就是Object.prototype.x的值(outer)。结果,外部函数的作用域(包含x = 'inner'的作用域)就不会被解析了。    */        (function foo(){            alert(x); // 提示框中显示:outer        })();  })();复制代码
不过,更高版本的SpiderMonkey改变了上述行为,原因可能是认为那是一个安全漏洞。也就是说,“特殊”对象不再继承Object.prototype了。不过,如果你使用Firefox 3或者更低版本,还可以“重温”这种行为。

另一个把内部对象实现为全局Object对象的是黑莓(Blackberry)浏览器。目前,它的活动对象(Activation Object)仍然继承Object.prototype。可是,ECMA-262并没有说活动对象也要“像调用new Object()表达式那样”来创建(或者说像创建保存NFE标识符的对象一样创建)。 人家规范只说了活动对象是规范中的一种机制。

那我们就来看看黑莓里都发生了什么:

  Object.prototype.x = 'outer';    (function(){        var x = 'inner';        (function(){            /*      在沿着作用域链解析x的过程中,首先会搜索局部函数的活动对象。当然,在该对象中找不到x。      可是,由于活动对象继承自Object.prototype,因此搜索x的下一个目标就是Object.prototype;而      Object.prototype中又确实有x的定义。结果,x的值就被解析为——outer。跟前面的例子差不多,      包含x = 'inner'的外部函数的作用域(活动对象)就不会被解析了。      */            alert(x); // 显示:outer          })();  })();复制代码

发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码:点击我更换图片
最新评论 更多>>

推荐热点

  • Gb2312转utf-8编码的方法(vbs+js)
  • 如何使用Ajax技术开发Web应用程序(1)
  • js跳转路径问题
  • JavaScript模仿桌面窗口
  • 用js检测两个线段是否相交
  • 运用JavaScript构建你的第一个Metro式应用程序(on Windows
  • 我知道的JavaScript -- 设计模式(桥接)应用之 – 验证器
  • 我是如何去了解jquery的(六),案例之幻灯片轮换
  • Jquery封装幻灯片效果
网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
Copyright © 2008-2015 计算机技术学习交流网. 版权所有

豫ICP备11007008号-1