От этого примера мне даже поплохело...Вот еще примерчик
--------------------------------------
function init() { var temp=10 func1=new Function("alert(temp)") func2=function(){alert(temp)} }
init()
temp=99
func1() func2()
--------------------------------------
Всё на самом деле просто.
{ var temp=10;
Переменная temp -- локальная, т.е. по выходе из блока связь между именем "temp" и числом "10" теряется навсегда.
func1=new Function("alert(temp)")
"alert(temp)" -- это строка, которая "литерально" представляет тело функции. Сама по себе эта строка не содержит вообще никаких связей, "temp" в этой строке для интерпретатора -- просто четыре символа. "Вычисление" temp, т.е. связывание имени со значением, происходит в момент _вызова_ функции. Как будто вызов func1 равнозначен eval("alert(temp)") (хотя на самом деле это не так).
func2=function(){alert(temp)}
Здесь всё по-другому. Функция, записанная таким образом (это называется "лямбда-выражение") сохраняет ("замыкает") связи, существующие в данный момент. В функции сохраняется копия текущей _локальной_ таблицы символов (имя-значение). Это можно представить себе так, что к телу функции неявно приписываются необходимые var декларации.
Это явление ("замыкание") можно очень интересно использовать. Самый, пожалуй, популярный пример -- назначение метода в качестве обработчка события.
--------------------------------------
<button ID=TEST_1></button> <button ID=TEST_2></button>
<script> function MyObj(oNode,sName) { .this.name=sName; .var me=this; .oNode.onclick=function(){me.clicked()} }
MyObj.prototype.clicked=function() { .alert("Clicked "+this.name); } window.onload=function() { .obj1=new MyObj(TEST_1,"name one"); .obj2=new MyObj(TEST_2,"name two"); } </script>
--------------------------------------
Обратите внимание, как в конструкторе MyObj "замыкается" указатель на самого себя. Реализовать это без замыкания было бы довольно сложно. |