Объявления переменных поднимаются до верха функции.Это не будет иметь никакого значения, если, конечно, вы не говорите об объявлении переменной в новой области видимости функции.
РЕДАКТИРОВАТЬ: Сначала не заметил, вашпервый пример не объявлял i
с var
.Это не очень хорошая практика.
РЕДАКТИРОВАТЬ:
Как правило, рекомендуется избегать создания глобальных переменных, чтобы избежать конфликтов с другими сценариями, которые могут устанавливать глобальные переменные.
Всякий раз, когда вы используете переменную, не объявив ее с помощью var
, она становится глобальной.
Единственный способ создания новой области видимости переменной в JavaScript - это тело функции.Функции могут быть вложенными друг в друга, создавая цепочку областей видимости, которая начинается с самой внутренней функции и заканчивается глобальной областью видимости.
Из-за этого, как правило, весь ваш код помещается в вызываемую функциюнемедленно.Таким образом, любые переменные, которые вы создаете с помощью var
, не будут в конечном итоге глобальными.
(function() { // <-- create a function
// place your code in here
// use "var" when declaring variables so they don't become global
var name = "patrick dw";
alert( name );
})(); // <-- invoke the function immediately so your code runs
В предыдущем примере переменная name
будет локальной для немедленно вызываемой функции и не будетзагрязняют глобальную область видимости.
Поскольку обход области видимости переменной требует некоторых ресурсов, люди часто вызывают эту функцию с некоторыми передаваемыми аргументами, такими как window
.
(function( window, undefined ) {
// now the window object is referenced locally. Better for performance.
var name = "patrick dw";
alert( name );
})( window ); // <-- invoke the function passing in the global "window" object
Теперь на объект window
ссылаются локально внутри вашей функции, поэтому, если вы получите доступ к какому-либо свойству window
, ему не придется полностью следовать цепочке областей действия за пределами вашей функции.
Я также включил в функцию дополнительный параметр undefined
, но не передал ему аргумент.Это должно помочь избежать странной проблемы, вызванной некоторыми плохими методами кодирования.Но это еще одна проблема.
Теперь, взяв ту же функцию, если бы мы не использовали var
при объявлении нашей переменной name
, она автоматически стала бы глобальной.Я обновлю пример и добавлю еще одну область действия функции для иллюстрации.
(function( window, undefined ) {
// create a function
function some_func() {
name = "patrick dw"; // didn't use "var" when declaring!!
alert( name );
}
some_func(); // call our function
alert( window.name ); // but "name" is also accessible from the global window
})( window );
alert( name ); // outside those functions, we're global, and again we can see that
// the "name" variable is accessible
Итак, как вы можете видеть, мы никогда не объявляли var name
, поэтому она стала автоматической глобальной переменной, даже если онабыло вложено две функции глубиной.
Это источник многих ошибок, и это причина, почему вы должны быть очень осторожны, чтобы использовать var
.
Наконец, я быобратите внимание, что ECMAScript 5 запрещает некоторые плохие практики кодирования при запуске вашего кода в "strict mode";
.Не многие браузеры в настоящее время реализуют strict mode
, но было бы полезно периодически проверять ваш код в одном из них.
Вот таблица совместимости для ECMAScript 5 .Строгий режим находится внизу.Вы увидите, что Firefox 4 поддерживает его.
Вот пример:
(function( window, undefined ) {
"strict mode"; // <-- use the strict mode directive
name = "patrick dw"; // In Firefox 4, you should get a ReferenceError in the console
// because "name" was never declared with "var"
})( window );