Вход/Регистрация
Основы программирования на JavaScript
вернуться

Кан Марк

Шрифт:

Internet Explorer имеет два отдельных сборщика мусора: один для JavaScript и другой для объектов DOM. При выгрузке страницы браузер просматривает и удаляет весь код JavaScript и все объекты DOM со страницы. Утечка происходит, когда имеются циклические ссылки из объекта DOM в JavaScript и снова на объект DOM или из JavaScript-->Dom-->Javascript. Internet Explorer запутывается и не удаляет объекты при циклической ссылке.

var someInput = document.getElementById('inputbox');

var someFunction = function{

alert(someInput.value);

}

someInput.onclick = someFunction;

Здесь представлен бесконечный цикл в терминах замыканий. Объект DOM someInput вовлечен в замыкание с функцией someFunction и наоборот. Браузер не может определить, что удалить в первую очередь, поэтому в результате имеем утечку памяти.

Замыкания создают, часто даже не осознавая этого. Возьмем, например, простую функцию:

function Animal(name){

this.sleep = function{ alert(name+' спит: Хрррр'); }

}

Можно не заметить этого, но переменная 'name' в функции sleep приходит из родительской функции Animal. Это создает замыкание.

Даже определение простейшей функции может создавать замыкание:

var x = 5;

var n = function{

y=10;

return y;

}

Здесь также создается замыкание, хотя на первый взгляд это не так. Почему? Когда мы создаем функцию, она получает доступ ко всем переменным в своей текущей области действия, поэтому мы создаем новую ссылку на переменную х.

Теперь мы подошли к понятию области действия. Каждая функция имеет свою область действия, в которой она выполняется. Все области действия кода сохраняются во внутреннем стеке памяти. Когда создается замыкание, оно получает доступ к одной из этих областей действия. Если создается несколько замыканий в одной и той же области действия, то каждое замыкание будет в действительности указывать на одинаковые копии каждой переменной области действия. Например:

var x = 5;

var alertX1 = function{ alert(x); }

x = 10;

var alertX2 = function{ alert(x); }

alertX1;

alertX2;

Обе функции в этом случае выведут 10. Почему? Потому что они обе указывают на одну и ту же копию х.

Если изменить x в любой точке, то обе функции отразят это. Как это исправить? Проще всего изменить область действия замыкания:

function makeClosure(x){

return function{ alert(x); }

}

var x = 5;

var alertX1 = makeClosure(x);

x = 10;

var alertX2 = makeClosure(x);

alertX1; // 5

alertX2; // 10

Это решает проблему. Если, однако, этот код создавал утечку памяти, то утечка будет существенно больше, чем в предыдущем примере; и также используется больший объем памяти. Оказывается, что в действительности имеется три различных области действия в этом простом примере:

Можно видеть, что переменная х копируется в каждую из двух областей действия. Это связано с тем, что x является строкой или числом. JavaScript всегда передает строки и числа по значению - то есть всегда делается копия переменной. С объектами все происходит иначе. Если х является функцией, массивом или базовым объектом, то в этом случае ссылка в двух наших функциях происходит на одну и ту же копию x и поэтому в результате выводимое сообщение будет одинаковым:

function makeClosure(x){

return function{ alert(x.val); }

}

var x = {val:5};

var alertX1 = makeClosure(x);

x.val = 10;

var alertX2 = makeClosure(x);

alertX1; // 10

alertX2; // 10

Отличие состоит в том, что x теперь является объектом. Каждая из дополнительных областей действия указывает на одну и ту же копию x. При изменении значения x оно изменяется в каждой области действия, в которой х упоминается.

  • Читать дальше
  • 1
  • ...
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: