在JavaScript中使用inline函数的问题

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

    我们在JavaScript中编写代码,对于定义函数的语句:
function foo()
{
    
// TODO: . . .
    return x;
}

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

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

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

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

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

 function TestObject.prototype.Render(doc, id)
 {
    
var span = doc.createElement('SPAN');
    span.Object 
= this;
    
this.m_Element = span;

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

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

   
 Normal Method   Inline Method 
 Initialized  27.4 M 27.4 M
 Rendered  33.4 M 35.2 M

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

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

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


function TestObject(name)
{
    
this.m_Name = name;
    
this.m_Description = '';
    
this.m_Element = null;
         
    
this.toString = function()
    
{
         
return '[class TestObject]'; 
    }

}


function TestObject.prototype.Render(doc, id)
{
    
var span = doc.createElement('SPAN');
    span.Object 
= this;
    
this.m_Element = span;

    
if ( id == "NamedMethod" )
    
{
         span.onclick 
= asdf;
    }

    
else
    

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

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


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

</script>
    
<script language="javascript">
function ReleaseElements()
{
    
var room = document.getElementById('container');
    
var spans = room.all.tags('SPAN');
    
for ( var i=0 ; i < spans.length ; ++i )
    
{
         spans[i].Object 
= '';
    }

}
 
</script>
</body>
</html>

相关文章

  • js实现淘宝浏览商品放大镜功能

    js实现淘宝浏览商品放大镜功能

    这篇文章主要为大家详细介绍了js实现淘宝浏览商品放大镜功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-10-10
  • js执行字符串代码的具体实现

    js执行字符串代码的具体实现

    这篇文章主要给大家介绍了js执行字符串代码的具体实现,需要的朋友可以参考下
    2024-06-06
  • JavaScript null和undefined区别分析

    JavaScript null和undefined区别分析

    在JavaScript开发中,被人问到:null与undefined到底有啥区别?
    2009-10-10
  • JavaScript实现将数组中所有元素连接成一个字符串的方法

    JavaScript实现将数组中所有元素连接成一个字符串的方法

    这篇文章主要介绍了JavaScript实现将数组中所有元素连接成一个字符串的方法,涉及javascript中采用join方法进行数组转化的技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • 前端layui table表格勾选事件以及常见模块详解

    前端layui table表格勾选事件以及常见模块详解

    Layui 是一个非常流行的前端框架,其中的table组件可以帮助您实现复选框功能,下面这篇文章主要给大家介绍了关于前端layui table表格勾选事件以及常见模块的相关资料,需要的朋友可以参考下
    2024-08-08
  • js实现上下滑动轮播

    js实现上下滑动轮播

    这篇文章主要为大家详细介绍了js实现上下滑动轮播,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • JS读写CSS样式的方法汇总

    JS读写CSS样式的方法汇总

    这篇文章主要为大家详细汇总了JS读写CSS样式的方法,内容详尽,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • ECharts绘制立体柱状图(圆柱体)详细示例

    ECharts绘制立体柱状图(圆柱体)详细示例

    echarts实现平面的柱状图很顺利,但是用户为了美观立体感,用到圆柱体图,下面这篇文章主要给大家介绍了关于ECharts绘制立体柱状图(圆柱体)的相关资料,需要的朋友可以参考下
    2023-11-11
  • 推荐20家国外的脚本下载网站

    推荐20家国外的脚本下载网站

    脚本使网站更加动态和更具交互性,但是写好一个脚本并不是一件容易的工作,因此一些开发者会到网站下载其他人分享的脚本来使用。今天,本文向大家推荐20佳国外的脚本下载网站。
    2011-04-04
  • JavaScript中三个等号和两个等号的区别(== 和 ===)浅析

    JavaScript中三个等号和两个等号的区别(== 和 ===)浅析

    javascript中比较运算符'=='与'==='可能大家用的比较多,但是大家对他的区别不是很清楚,接下来小编给大家介绍下js中三个等号和两个等号的区别(== 和 ===),感兴趣的朋友可以参考下
    2016-09-09

最新评论