1

Playing with typescript, I found that when I use array destructuring, it generates some unusual code where variable initialization precedes its declaration, i.e. in following example console shows "undefined"

(function () {
    var _a = 1;
    _c = _a;
    var _c;
})();
console.log(_c);

> ReferenceError: _c is not defined

Why variable _c does not became global?

Somescout
  • 33
  • 8

2 Answers2

2

In Javascript, all variable declarations are hoisted to the top of the scope in which they are declared before any code is actually run. So your code example:

(function () {
    var _a = 1;
    _c = _a;
    var _c;
})();
console.log(_c);

Is evaluated like this:

(function () {
    var _a;
    var _c;
    _a = 1;
    _c = _a;
})();
console.log(_c);

Thus, _c is declared locally before it is actually referenced or used and thus it is not an implicit global because it is declared within the scope in which it is referenced and the hoisting ensures it is declared at the beginning of that scope, no matter where the var _c; declaration is within the scope.


Here are some references on the hoisting concept:

JavaScript Scoping and Hoisting

MDN - var statement

Demystifying JavaScript Variable Scope and Hoisting

JavaScript Hoisting Explained

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Thanks for detailed explanation. But it's really strange language concept. – Somescout May 13 '15 at 09:46
  • @Somescout - it's not strange at all. The parse step gathers all the variable and function declarations for a scope before the code is executed. That works just like compiled languages. Javascript just doesn't force you to place all the definitions at the top of their scope. – jfriend00 May 13 '15 at 09:48
  • By "strange" I mean that behavior of preceding code can be changed by latter lines. It is almost always unexpected. (But of course, declaring and relying on global variables inside function is a bad practice itself). – Somescout May 13 '15 at 09:55
  • @Somescout - It's only unexpected if you don't know that Javascript collects all declarations within a scope at parse time and they are available anywhere in the scope. Once you know that, it doesn't seem strange. What I think is "strange" is that use of an undeclared variable is ever allowed. Thank goodness for strict mode which makes that an error. – jfriend00 May 13 '15 at 09:57
  • I'd rather disagree (I know and understand hoisting now, but it still seems very strange language design to me), but it's going offtop on top speed. – Somescout May 13 '15 at 10:01
  • @Somescout - in the JS implementation, a scope is an internal object and the definition of that object is pre-created by the parser, not by the interpreter at runtime. That's how they chose to implement it. It means that there are a fixed set of local variables in a scope. It doesn't vary depending upon how the code branches (e.g. if a branch skips over a `var` statement). In many ways, this simplifies the implementation and eliminates many odd error states or weird bugs. FYI, ES6, adds `let` which is like `var`, but has block scope, not just function scope. – jfriend00 May 13 '15 at 10:08
0

All variables under functions are Local variables.

Vinayak
  • 415
  • 3
  • 21