Нет необходимости определять переменную дважды - PullRequest
5 голосов
/ 20 октября 2010

Если переменная может быть определена в функции , даже если значение не назначено, она становится локальной переменной

Итак, testB () лучшее программирование?

var test = 'SNAP!'
function testA(boolean) {
    if (boolean) var test = 'OK';
    else var test = null;
    alert(test);
}
function testB(boolean) {
    if (boolean) var test = 'OK';
    alert(test);
}
testA(true); // 'OK'
testB(true); // 'OK'
testA(false); // null
testB(false); // undefined, no error

В моем конкретном случае глобальное значение теста ('SNAP!') Не ожидается и не требуется.

Ответы [ 3 ]

6 голосов
/ 20 октября 2010

Вы не можете объявить переменные условно.

Почему?

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

function foo () {
  if (false) {
    var test = 'foo'; // never executed
  }
  return test;
}
foo(); // undefined

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

Переменные инициализируются с undefined.

Кроме того, идентификаторы в локальной области видимости shadow остальные с тем же именем, расположенные выше в цепочке областей действия, например:

var test = 'global';
function bar () {
  alert(test); // undefined, not "global", the local variable already declared
  var test = 'xxx';
}
bar();

Если переменная test нигде не была объявлена, будет выдано ReferenceError:

function foo () {
  return test;
}

try {
  foo(); // ReferenceError!!
} catch (e) {
  alert(e);
}

Это одна из причин того, почему, например, JSLint рекомендует только один var оператор в верхней части функций, потому что, например, первый фрагмент действительно будет напоминать это при выполнении:

function foo () {
  var test; // var statement was "hoisted"
  if (false) {
    test = 'foo'; // never executed
  }
  return test;
}
foo(); // undefined

Другая причина заключается в том, что блоки не вводят новую лексическую область видимости, это делают только функции, поэтому наличие в выражении оператора var может заставить вас думать, что срок жизни переменной ограничен только этим блоком, но дело не в этом.

Объявления вложенных функций будут иметь аналогичное поведение подъем , они будут объявлены до выполнения кода, но они также инициализируются в этот момент:

function foo () {
  return typeof bar;
  // unreachable code:
  function bar() {
    //..
  }
}
foo(); // "function"
4 голосов
/ 20 октября 2010

Если переменная не нуждается в манипулировании какими-либо другими функциями , сохраните переменную внутри функции с помощью var foo;.

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

(function() {
   var president='bush';

   function blah() {
     president='reagan';
   }

   function meh() {
     president= 'carter';
   }

   document.getElementById('reagan').onclick=blah;
   document.getElementById('carter').onclick=meh;


})();

alert( president ) // undefined

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

Итак, если вы не имеете дело с несколькими функциями, меняющими одну и ту же переменную, оставьте их локальными для функции.

2 голосов
/ 20 октября 2010

Тест B лучше программирования? Нет, потому что он дает неожиданный результат "undefined" (по крайней мере, я был удивлен этим), и его трудно прочитать.

Как правило, переменные должны быть ограничены областью, которая их требует, поэтому, если переменная «test» не требуется вне функции, она должна быть объявлена ​​локальной. Чтобы избежать путаницы, объявите переменную перед ее использованием:

function testC(boolean) {
    var test;
    if (boolean) {
        test = "OK";
    }
    else {
        test = null;
    }
    alert(test);
}

Если вы действительно не хотите изменить глобальную версию "test", в этом случае не используйте ключевое слово var внутри функции.

Если вы когда-нибудь используете одно и то же имя для локальной и глобальной переменных, вы можете переименовать одну из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...