Из-за переменной подъемки в Javascript нет технических различий в исполнении между var
, находящимся в верхней части функции или внутри цикла for
. Если это все, о чем вы заботитесь, тогда вы можете сделать это в любом случае.
Просто чтобы обновить память, Javascript hoisting означает, что код, подобный вашему второму блоку кода, анализируется, а затем выполняется так же, как ваш первый блок кода. Все объявления var
внутри функции автоматически переходят в верхнюю часть области функций перед выполнением. Присвоения этих переменных сохраняются там, где они находятся в коде - только перемещение объявления переменной.
Итак, разница больше о том, как вы хотите, чтобы код выглядел. Когда вы помещаете определения var
в цикле for
, это делает код похожим на то, что переменные создаются заново для каждой итерации цикла for
, хотя это не так. Им присваивается значение каждой итерации цикла, но новая переменная не создается. Это будет иметь место, если вы использовали let
вместо var
, поскольку let
имеет область действия блока, тогда как var
имеет только функцию.
В целом, рекомендуется только поставить код внутри цикла, который фактически должен находиться внутри цикла. Хотя это фактически ничего не меняет в выполнении, является ли var
внутри или вне цикла, это просто часть хорошей практики, тогда как другой код внутри или вне цикла может иметь значение.
В вашем случае, я думаю, это было бы лучше практика:
function abc(){
var liTags = document.getElementsByTagName('LI');
var divTags = document.getElementsByTagName('DIV');
var len = Math.min(liTags.length, divTags.length);
var a,b;
for(var i = 0; i < len; i++){
a = liTags[i].width;
b = divTags[i].width;
// now do something with a and b
}
return;
}
Здесь вы удалили два вызов document.getElementsByTagName()
из цикла, который сделает разницу ОГРОМНОЙ производительности.
Обновление в 2017. Javascript версии ES6, теперь поддерживает const
и let
для объявления переменных. Они ограничены областью, а не областью действия, например var
, поэтому, если вы объявите один из них в блоке цикла for
, тогда будет создана новая и отдельная переменная, созданная для каждого вызова цикла for
.Хотя это не приведет к существенной разнице в исполнении кода, который вы показали, это может иметь значение, если в цикле был асинхронный код, который ссылается на переменную, которую вы объявляете. В случае const
или let
, используемых в теле цикла, каждый асинхронный вызов получит свою собственную отдельную копию переменной, которая иногда может быть очень удобной.
for(var i = 0; i < len; i++){
let a = liTags[i].width;
let b = divTags[i].width;
$.get(someUrl).then(function(data) {
// each call to $.get() here in the loop has it's own a and b
// variables to use here, which would not be the case with var
});
}
В любом случае 'var' будет поднят, в том числе и в '' for''. IMO * not *, объявляющий их в верхней части функции (включая ту, что у вас нет), несет * импликацию *, что подъем не существует, а просто заставляет думать об этом сложнее, особенно когда будущий читатель может не полностью grok JS. И это просто шум. –
Единственный раз, когда вам нужно использовать VAR, когда переменная будет находиться за пределами (глобальная). Выполнение этого внутри функции означает, что вы VAR это или нет, оно падает, когда функция выполняется в любом случае. Неважно, если вы делаете это внутри цикла или нет. Это потому, что внутри функции это бесполезно. – durbnpoisn
@ durbnpoisn. Хм - может быть, я вас не понимаю, но это кажется противоположным моему пониманию. Если я не использую ключевое слово 'var' для определения переменной внутри функции, она будет втянута в глобальную область действия и, таким образом, создаст другие проблемы, не связанные с этим вопросом. – user1167442