Первый. Переменные. Оператор var и магия областей определения переменных
Здравствуйте
С сегодняшнего дня я начинаю вести цикл статей об оптимизации в JavaScript!
В цикле статей я постараюсь рассмотреть все аспекты и принципы оптимизации, разные трюки и наилучшие варианты кода для той или иной ситуации, а также буду объяснять, “Почему так?”. Буду стараться рассматривать ситуации от макро-оптимизации до мини- и микро-оптимизации
Это самая первая статья. Сегодня я расcкажу вам о переменных в JavaScript.
Переменные в JavaScript назначаются с помощью оператора var.
var name2 = 'строка';
var name3 = function( a ){
alert( 'Передали: ' + a );
};
var name4 = new Object();
var name5 = /^регулярное выражение$/g;
// Используем переменную
alert( 'Число ' + name1 );
Всё, что создавалось не с помощью оператора var – не переменная.
name7 = 'Строка в свойстве глобального объекта - не переменная';
window.name8 = 'Назначение name7 аналогично такой записи';
this.name9 = 'Или такой';
И самое первое правло в цикле статей
С помощью оператора var можно объявить несколько переменных используя запятую после значения переменной.
Синтаксис:
Следуя ему мы уже можем ускорить свой код:
name1 = 55,
name2 = 'строка',
name3 = function( a ){
alert( 'Передали: ' + a );
},
name4 = new Object(),
name5 = /^регулярное выражение$/g;
// Используем переменную
alert( 'Число ' + name1 );
Интерпретатор единожды увидев оператор var создаёт переменные по циклу, идущие через запятую.
Выходит, намного выгоднее использовать один оператор var и перечислить все переменные!
Далее советую очень строго придерживаться этого правила, оно вам поможет в будущем
Далее поговорим подробнее об определении переменных… в функциях!
Объявляя переменную в функции, мы прикрепляем её к этой функции, а точнее к её области видимости переменных!
Область видимости переменной – текущая функция. Если переменная объявлена вне функции, то ее область видимости – глобальный объект window.
То есть:
alert( name1 );
function name2(){
var name1 = 88;
alert( name1 );
};
name2();
alert( name1 );
Здесь переменная, объявленная внутри функции становится видна только в области видимости переменных данной функции, а также ещё во вложенных функциях в эту функцию(благодаря замыканиям, о которых позже):
alert( name1 );
function name2(){
var
name1 = 88,
fn = function(){
alert( name1 );
};
fn();
};
name2();
alert( name1 );
Это значит, что можно полностью использовать переменные, назначенные в функциях, которые породили нашу текущую функцию:
alert( name1 );
function name2(){
// без var
name1 = 88;
alert( name1 );
};
name2();
alert( name1 );
Такой подход очень удобен! Но немного теории: когда в нашей функции name2 идёт обращение к переменной name1, наша функция ищет name1 в своей области видимости переменных. Если она не обнаружила переменную с таким именем, то функция просматривает области видимости переменных в функциях, которые породили нашу функцию(точнее являются её обёртками). Если она нашла переменную с таким именем, то начинает полноценно управлять её(в нашем случае – это назначение переменной name1 числа 88). Если же функция не нашла таких переменных в этом процессе – она производит поиск в области видимости объекта window.
Отсюда отчётливо вытекает третье правило микро-оптимизации:
Чтобы предотвратить поиск функцией переменных в областях определения переменных “функций-обёрток”, нужно всего лишь назначить в этой функции переменную, значение которой будет либо равно нужной переменной, либо будет являться ссылкой на нужную переменную.
Сразу пример для большего понимания:
name1.fn1 = function( number ){
return number * number;
};
function name2(){
// Создаём ссылку на объект
var obj1 = name1;
for( var i = 1; i < 10; i++ )
document.write(
i + ' умножить на ' + i
+ ' равно ' + obj1.fn1( i )
+ '<br>'
);
};
name2();
Или же сохраняем имя объекта – передаём его в функцию:
name1.fn1 = function( number ){
return number * number;
};
function name2( name1 /*Ссылка создаётся автоматически*/ ){
for( var i = 10; i < 21; i++ )
document.write(
i + ' умножить на ' + i
+ ' равно ' + name1.fn1( i )
+ '<br>'
);
};
name2( name1 );
Пример реального использования? Да пожалуйста ![]()
Библиотека jQuery 1.4:
// Здесь в нашем коде спокойно используем window
// И знаем то, что он вызывается довольно быстро ;)
})( window );
Спасибо за внимание и удачи
С уважением, Regent
Либо скачать новый нормальный браузер
Комментарии(12)
Спасибо за доходчивую и интересную подачу материала.
Да и весь блог vl.vg необычный. Автор молодец, при возможности пропиарю.
Думаю теперь я смогу полюбить JavaScript.
Еще, не знаю, в тему или нет (свойство объекта это почти тоже, что переменная) - чем больше вложенность свойств в объекте, тем медленне скорость доступа к объекту, т.е.:
window.myobj.myvar.anothervar.target = 0;
Эту тему планирую рассмотреть в статье про кеширование. Вот там и буду писать, почему так лучше
code += i + ' умножить на ' + i
+ ' равно ' + name1.fn1( i )
+ '<br>';
};
document.write( code );
Чтобы совсем не запутаться, пока будем называть всё то, что создано с помощью оператора var - переменные.
Спасибо, тоже собираюсь рассмотреть эту ситуацию в статье о кешировании!
Спасибо за комментарий =)
p.s.: Жабаскриптовый беспредел с подсветкой в этом блоге очень доставляет (>_<")
Про беспредел не понял
Конечно, из Правила 3 это и так можно понять, но замедление поиска переменных - не единственный недостаток глобальной области видимости.
Мы об этом говорили 10 января в самой первой статье в рубрики Оптимизации =)
Статья называется "Анонимная функция – необузданная мощь JavaScript!" и находится по адресу http://vl.vg/10.01.2010/anonim-function/
Там даже в конце есть
если не ошибаюсь, то в данном случае:
function name2(){
....};
точка с запятой не нужна.
А в случае var name2 = function(){...}; нужна, т.к. это определение переменной.
В примере с ускорением поиска переменных можно создать ссылку не на объект а прямо на вызываемую функцию, это еще несколько ускорит работу, т.к. обращение к полю/методу объекта - тоже занимает время.
Спасибо за статью. Весьма познавательно
На счёт функции вы совершенно правы, но это уже будет относится к будущей теме кеширования