当前位置: 首页 > 图文教程 > 网络编程 > Javascript > 在JavaScript中使用inline函数的问题

Javascript
Javascript 篱式条件判断
FormValidate 表单验证功能代码更新并提供下载
IE php关于强制下载文件的代码
Javascript 注册事件浅析
js网页中随意拖动的小方块实现代码
javascript charAt() arr[i]数组实例代码
jquery HotKeys轻松搞定键盘事件代码
JQUERY复选框CHECKBOX全选,取消全选
jquery复选框CHECKBOX全选、反选
JQUERY CHECKBOX全选,取消全选,反选方法三
一个简单但常用的javascript表格样式_鼠标划过行变色 简洁实现
javascript用DIV模拟弹出窗口_窗体滚动跟随
Javascript多种浏览器兼容写法分析
JavaScript监测ActiveX控件是否已经安装过的代码
javascript结合Cookies实现浏览记录历史
javascript textarea字数限制
动态修改DOM 里面的 id 属性的弊端分析
js实现右下角窗口弹出窗口效果
javascript移动的盒子效果代码
js链接确认提醒功能

Javascript 中的 在JavaScript中使用inline函数的问题


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-12   浏览: 247 ::
收藏到网摘: n/a

前段时间被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>