Основы программирования на JavaScript
Шрифт:
Замыкания создают, часто даже не осознавая этого. Возьмем, например, простую функцию:
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
Отличие
Как избежать утечки памяти при использовании замыканий? Необходимо избегать использования циклических ссылок. Наиболее распространенной причиной утечки памяти является присоединение событий, таких, как событие onclick, к объектам DOM.
Часто совершенно невинный с виду код будет создавать утечку и ее бывает крайне сложно обнаружить. К счастью, протестировать наличие утечки памяти достаточно легко. Если при каждом обновлении страницы используемая память увеличивается, то приложение имеет утечку. Отследить, где это происходит, совершенно другая задача, но по крайней мере теперь известно о наличии проблемы!
Следующая лекция будет посвящен основам приложений AJAX!
Лекция 10. Основы приложений AJAX
В последнее время термин AJAX получил широкое распространение. По сути, это необычное название технологии, которая уже давно существует. Однако за последний год JavaScript в стиле AJAX стал очень популярным у многих разработчиков, и мы начинаем видеть, как с его помощью стали создавать различные интересные вещи. Google Maps и GMail являются двумя наиболее широко известными приложениями AJAX, но в последнее время и другие компании по всему миру начали использовать ее на своих сайтах.
AJAX означает "Asynchronous JavaScript and XML", т.е. Асинхронный JavaScript и XML. В действительности AJAX состоит из JavaScript, как и любое другое приложение, и соединения XMLHTTP с Web-сервером. Вот и все! Общая идея заключается в том, что можно извлекать с сервера данные просто по мере необходимости, не обновляя всю страницу.
Прежде всего AJAX почти всегда опирается на серверный язык, такой, как PHP или ASP. Когда пользователю необходимо получить новые данные, JavaScript запрашивает их, а сервер, вероятно, запросит базу данных и затем вернет данные. Эти данные можно вернуть в различной форме. Если они структурированы, то это будут обычно данные XML или JSON. Если это очень простые данные (такие, как получение описания какого-то объекта), то можно часто увидеть людей, которые просто записывают эти данные непосредственно в ответ AJAX.