В JavaScript функции являются объектами, как и другие объекты. Когда вы делаете это:
var myFunct = function () {
alert("hello");
};
... вы создаете функцию и присваиваете ссылку этой функции на переменную myFunct
. Затем, когда вы делаете это:
markers["myIndex"] = myFunct;
... вы назначаете другую ссылку для этой функции на markers["myIndex"]
. Таким образом, независимо от всего, что может произойти с переменной myFunct
, поскольку markers["myIndex"]
все еще имеет ссылку на функцию, функция сохраняется в памяти.
Но отдельно , в вашем вопросе есть и более тонкое недоразумение: вы сказали:
myFunct
- это "var" (поэтому, когда example()
закончит, он будет уничтожен, потому что он локальный)
Это не так в JavaScript. В JavaScript локальные переменные на самом деле являются свойствами скрытого объекта, называемого (глубокий вдох) объектом привязки переменной из контекста выполнения (давайте просто назовем его «переменным объектом»). Этот объект связан с конкретным вызовом example
: он создается при выполнении вызова example
. Теперь, в обычном порядке, когда возвращается example
, если ничто не имеет какой-либо выдающейся ссылки на объект переменной, тогда вы совершенно правы, что он подходит для сборки мусора. Но в вашем случае что-то имеет ссылку на переменный объект: созданную вами функцию. Когда вы создаете функцию, она получает неявную ссылку на объект переменной для контекста, в котором она была создана, и сохраняет эту ссылку до тех пор, пока функция существует. Таким образом, даже если создаваемая вами функция не ссылается ни на что в объекте переменной для вызова example
, она, тем не менее, имеет эту ссылку, и объект переменной не может быть восстановлен до тех пор, пока ничего не имеет ссылки на функция больше. Вот как работают замыкания . Несмотря на вышеприведенный текст, замыкания не сложны , они действительно очень просты, когда вы понимаете, как они работают.
(Я просто отмечу здесь, что некоторые движки JavaScript достаточно тщательно анализируют код, чтобы они могли возвращать переменные объекты, даже когда есть ожидающие замыкания, которые ссылаются на них. В частности, если замыкания [функции] на самом деле не используют какой-либо из свойства объекта переменной, и они не используют eval
, тогда механизм может быть в состоянии освободить объект переменной. Например, движок Chrome V8 делает это. Но это оптимизация времени выполнения; 1046 * концепция такая же, как описано выше.)