在JavaScript中使用inline函数的问题

    前段时间被IE和JavaScript脚本引擎的Memory Leak问题弄得郁闷坏了,不过幸好现在总算是柳暗花明了,并且找到了一些IE中使用脚本避免ML问题的方法。继续研究JavaScript的编写,有发现一些不算ML问题,但是可以节约IE内存使用的方法,在此和大家讨论讨论。

    我们在JavaScript中编写代码,对于定义函数的语句:

None.gif function  foo()
None.gif{
None.gif    
//  TODO: . . .
None.gif
     return  x;
None.gif}

可以说是在熟悉不过了。当然除了这种定义函数的方法,我们还有另外几种方法也能定义函数:

None.gif var  foo  =   function ()
None.gif{
None.gif    
//  TODO: . . .
None.gif
     return  x;
None.gif}

None.gif var  foo  =   new  Function('{ /* todo */ return  x;}');

    后两种方法定义的JavaScript函数,在调用起来和第一种没有任何效果上的区别。

    不过由于JavaScript是解释性语言,当我们定义一个函数的时候,解析引擎生成一个Function对象实例,然后把函数内容保存下来。所以每执行一次函数定义语句,就会生成一个函数。而不像编译语言,一个函数编译一次后就被任何语句调用。啊?难道JavaScript不能调用定义好的函数?不是这个意思了,当我们在制作JavaScript控件时,如果动态输出DHTML来作为控件的内容,就容易出现这样的问题。比如我们在一个HTML对象生成过程中,使用了inline方式定义的函数,那么这个元素生成几次,那个函数也就要同时生成几次。

None.gif  function  TestObject.prototype.Render(doc, id)
None.gif {
None.gif    
var  span  =  doc.createElement('SPAN');
None.gif    span.Object 
=   this ;
None.gif    
this .m_Element  =  span;
None.gif
None.gif    
if  ( id  ==   " NamedMethod "  )
None.gif    {
None.gif        span.onclick 
=  asdf;
None.gif    }
None.gif    
else
None.gif    { 
None.gif        span.onclick 
=   function ()
None.gif        {
None.gif            
var  asdf01  =  ['a', 's', 'd', 'f'];
None.gif            
var  asdf02  =  ['a', 's', 'd', 'f'];
None.gif            
var  asdf03  =  ['a', 's', 'd', 'f'];
None.gif            
var  asdf04  =  ['a', 's', 'd', 'f'];
None.gif            
var  asdf05  =  ['a', 's', 'd', 'f'];
None.gif            
var  asdf06  =  ['a', 's', 'd', 'f'];
None.gif            
var  asdf07  =  ['a', 's', 'd', 'f'];
None.gif            
var  asdf08  =  ['a', 's', 'd', 'f'];
None.gif            
var  asdf09  =  ['a', 's', 'd', 'f'];
None.gif            
var  asdf10  =  ['a', 's', 'd', 'f'];
None.gif            
var  asdf11  =  ['a', 's', 'd', 'f'];
None.gif            
var  asdf12  =  ['a', 's', 'd', 'f'];
None.gif        };
None.gif    }
None.gif    span.Name 
=   this .m_Description;
None.gif    span.innerText 
=   this .m_Name;
None.gif    span.style.display 
=  'block';
None.gif    
return  span;
None.gif }

    函数span.onclick = function()中的内容是用来占位置的,这样inline方式定义函数,每次Render()都就会生成一个新的函数对象。使用inline方式有什么不好呢?当对象实例多了的时候,会很明显的浪费内存空间呀,试验数据如下:

   
 Normal Method  Inline Method 
 Initialized  27.4 M27.4 M
 Rendered  33.4 M35.2 M

    // IE消耗的内存数量(PM+VM)

    单看绝对内存消耗差别不大,可是如果看相对内存消耗:(35.2-33.4)/(33.4-27.4) = 30% !!!,还是很可观的了,而且如果方法本省越大,inline时冗余数据就越多。

    附测试代码:
None.gif < html >
None.gif
< head >
None.gif    
< title > JScript Function Spending </ title >
None.gif    
< meta  name ="author"  content ="birdshome@博客园"   />  
None.gif
</ head >
None.gif
< body  onunload ="ReleaseElements()" >
None.gif    
< button  id ="NamedMethod"  onclick ="GenerateObjects(this)" >
None.gif        Append Normal Elements
</ button >
None.gif    
< button  id ="AnonymousMethod"  onclick ="GenerateObjects(this)" >
None.gif        Append Inline Elements
</ button >
None.gif    
< div  id ="container" >
None.gif    
</ div >
ExpandedBlockStart.gifContractedBlock.gif    
< script  language ="Javascript" > dot.gif
InBlock.gif
function GenerateObjects(elmt)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif    
var room = document.getElementById('container');
InBlock.gif    
for ( var i=0 ; i < 1000 ; ++i )
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif         
var obj = new TestObject('__Object__' + i);
InBlock.gif         room.appendChild(obj.Render(document, elmt.id));
ExpandedSubBlockEnd.gif    }
 
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
function TestObject(name)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif    
this.m_Name = name;
InBlock.gif    
this.m_Description = '';
InBlock.gif    
this.m_Element = null;
InBlock.gif         
InBlock.gif    
this.toString = function()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif         
return '[class TestObject]'; 
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
function TestObject.prototype.Render(doc, id)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif    
var span = doc.createElement('SPAN');
InBlock.gif    span.Object 
= this;
InBlock.gif    
this.m_Element = span;
InBlock.gif
InBlock.gif    
if ( id == "NamedMethod" )
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif         span.onclick 
= asdf;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif         span.onclick 
= function()
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif             
var asdf01 = ['a', 's', 'd', 'f'];
InBlock.gif             
var asdf02 = ['a', 's', 'd', 'f'];
InBlock.gif             
var asdf03 = ['a', 's', 'd', 'f'];
InBlock.gif             
var asdf04 = ['a', 's', 'd', 'f'];
InBlock.gif             
var asdf05 = ['a', 's', 'd', 'f'];
InBlock.gif             
var asdf06 = ['a', 's', 'd', 'f'];
InBlock.gif             
var asdf07 = ['a', 's', 'd', 'f'];
InBlock.gif             
var asdf08 = ['a', 's', 'd', 'f'];
InBlock.gif             
var asdf09 = ['a', 's', 'd', 'f'];
InBlock.gif             
var asdf10 = ['a', 's', 'd', 'f'];
InBlock.gif             
var asdf11 = ['a', 's', 'd', 'f'];
InBlock.gif             
var asdf12 = ['a', 's', 'd', 'f'];
ExpandedSubBlockEnd.gif         }
;
ExpandedSubBlockEnd.gif    }

InBlock.gif    span.Name 
= this.m_Description;
InBlock.gif    span.innerText 
= this.m_Name;
InBlock.gif    span.style.display 
= 'block';
InBlock.gif    
return span;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
function asdf()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif    
var asdf01 = ['a', 's', 'd', 'f'];
InBlock.gif    
var asdf02 = ['a', 's', 'd', 'f'];
InBlock.gif    
var asdf03 = ['a', 's', 'd', 'f'];
InBlock.gif    
var asdf04 = ['a', 's', 'd', 'f'];
InBlock.gif    
var asdf05 = ['a', 's', 'd', 'f'];
InBlock.gif    
var asdf06 = ['a', 's', 'd', 'f'];
InBlock.gif    
var asdf07 = ['a', 's', 'd', 'f'];
InBlock.gif    
var asdf08 = ['a', 's', 'd', 'f'];
InBlock.gif    
var asdf09 = ['a', 's', 'd', 'f'];
InBlock.gif    
var asdf10 = ['a', 's', 'd', 'f'];
InBlock.gif    
var asdf11 = ['a', 's', 'd', 'f'];
InBlock.gif    
var asdf12 = ['a', 's', 'd', 'f'];
ExpandedBlockEnd.gif}

None.gif
</ script >
ExpandedBlockStart.gifContractedBlock.gif    
< script  language ="javascript" > dot.gif
InBlock.gif
function ReleaseElements()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif    
var room = document.getElementById('container');
InBlock.gif    
var spans = room.all.tags('SPAN');
InBlock.gif    
for ( var i=0 ; i < spans.length ; ++i )
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif         spans[i].Object 
= '';
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
 
None.gif
</ script >
None.gif
</ body >
None.gif
</ html >
None.gif

转载于:https://www.cnblogs.com/birdshome/archive/2005/03/03/107134.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值