2012-05-04 3 views
17

Скажем, я пытаюсь выполнить этот фрагмент кода JavaScript. Предположим, что необъявленные vars и методы объявлены в другом месте выше, и что something и somethingElse оцениваются как boolean-true.Область JavaScript в блоке try

try { 
    if(something) { 
     var magicVar = -1; 
    } 

    if(somethingElse) { 
     magicFunction(magicVar); 
    } 
} catch(e) { 
    doSomethingWithError(e); 
} 

Мой вопрос: какова сфера magicVar и это хорошо, чтобы передать его в magicFunction, как я сделал?

+1

Мне кажется, как это просто вопрос о видимости переменных, а не переменная сфера в Ьгу блоке. –

ответ

17

Javascript имеет функцию scope.Это означает, что magicvar будет существовать с начала функции, которую она объявила до конца этой функции, даже если это утверждение никогда не выполняется. Это называется переменный подъемник. То же самое происходит с объявлениями функций, которые, в свою очередь, называются функцией подъема.

Если переменная объявлена ​​в глобальном масштабе, она будет видна всем. Это часть причины, по которой глобальные переменные считаются злыми в Javascript.

Ваш пример пройдет undefined в magicFunction, если something не соответствует действительности, так как magicVar не был назначен ни на что.

Хотя это технически обоснованный Javascript, он обычно считается плохим стилем и не будет проходить шашки стиля, такие как jsLint. Чрезвычайно неинтуитивное Javascript, как это будет выполняться без каких-либо ошибок

alert(a); //alerts "undefined" 
var a; 

POP ВИКТОРИН: Что делает следующий код делать?

(function() { 
    x = 2; 
    var x; 
    alert(x); 
})(); 
alert(x); 
+1

Пример, который вы дали, не совсем хорош, потому что он был 'undefined' в любом случае, потому что' window.a' 'undefined' – gdoron

+0

@gdoron Я не уверен, что вижу, что вы получаете. Если вы просто попытаетесь запустить 'alert (a)' все отдельно, то он выдает ошибку, например 'a is undefined''. –

+0

Дело в том, что 'a' _can_ не определено, потому что оно не определено в outerscope. Взгляните на это [demo] (http://jsfiddle.net/gdoron/H8c4n/3/) Если вы удалите 'var x', вы все равно получите тот же результат. – gdoron

1

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

Так что в вашем случае, если something является ложным, но somethingelse верно, вы будете называть magicFunction с его первым аргументом является undefined.

let ключевое слово, созданное в Javascript 1.9 и доступен (по состоянию на сегодня, 3 мая го 2012, и, насколько я знаю) только в Firefox, объявляет переменные с контекстными семантики вы, вероятно, привыкли.

5
  • Только в функциях javascript создайте новый контекст -closure.
  • Каждое определение переменной действительно является объявлением переменной в верхней части ее области и назначением в том месте, где определено определение.

вар

  • функции в области видимости
  • тали к вершине своей функции
  • redeclarations одного и того же имени в том же объеме, нет-OPS

Вы может хотеть читать MDN scope cheat sheet

Благодаря hoisting Вы даже можете сделать что-то вроде этого:

function bar() { 
    var x = "outer"; 

    function foo() { 
     alert(x); // {undefined} Doesn't refer to the outerscope x 
     // Due the the var hoising next:   
     x = 'inner'; 
     var x; 
     alert(x); // inner 

    } 
    foo(); 
} 

bar();​ 

bar();​ 

Demo

Таким образом, функция foo превращается в нечто вроде этого:

function foo() { 
    var x; 
    alert(x); // {undefined} Doesn't refer to the outerscope x 
    // Due the the var hoising next:   
    x = 'inner'; 
    alert(x); // inner 
}​ 

Мой вопрос: какова область действия magicVar d можно ли передать его в magicFunction, как я это сделал?

Определение хорошо ... Да код действителен, но это менее читаемыми тогда, если декларации переменных были на вершине, что и все.

+0

Я разорван! Я обожаю тебя и Питера Олсона. Имейте upvote :) – user5243421

+0

@DarrenGreen. **:) ** Не чувствуйте себя плохо. Просто выберите лучший ответ, который, как вы думаете, у вас есть. (Мне не нравится идея Stackoverflow о том, что принятые ответы появляются на вершине (я слышал _hoisting_? :)), не имеет смысла, что парень, который, вероятно, имеет меньше знаний по этому вопросу, решает, какой ответ лучше .) Если это ответ Петра, я в порядке с ним, я не конкурирую с ответами. – gdoron

+0

Ваша ссылка на чит-лист считается устаревшим. Любите большие предупреждающие бары на этой странице - вы не пропустите это! haha – jcollum

3

Благодаря JavaScript «грузоподъемный» (Google это), переменный код объявления переводится как:

function yourFunction() { 
    var magicVar; 
    try { 
     if(something) { 
      magicVar = -1; 
     } 

     if(somethingElse) { 
      magicFunction(magicVar); 
     } 
    } catch(e) { 
     doSomethingWithError(e); 
    } 

} //end of your function 

«Подъемны» перемещает все объявления переменных в начало функции. Таким образом, magicVar доступен везде в функции, но он не определен, пока вы не придадите ему значение.

У вашей переменной есть область действия.

14

Много других хороших ответов о том, как Javascript обрабатывает это с var, но я думал, что решить ситуацию let ...

Если переменная определена с let внутри try блока, он не будет в пределах внутри блока catch (или finally). Он должен быть определен в охватывающем блоке.

Например, в следующем блоке кода, вывод на консоль будет «снаружи»:

let xyz = "Outside"; 

try { 
    let xyz = "Inside"; 

    throw new Error("Blah"); 
} catch (err) { 
    console.log(xyz); 
} 
Смежные вопросы