在JavaScript中使用inline函数的问题 |
||||||||||||
|
前段时间被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函数,在调用起来和第一种没有任何效果上的区别 。 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方式有什么不好呢?当对象实例多了的时候,会很明显的浪费内存空间呀,试验数据如下:
// 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>![]() |
||||||||||||