0

I am trying to understand the concept of Lexical scope. As far as i know Lexical scope does not work backwards. In the below javascript code i have declared variable 'name' in scope3() function. But i tried to call it in scope1() and scope2() function. Since Lexical scope does not work backwards, I should have got "name is undefined" but it returns empty string. Can someone explain this?

var scope1 = function () {
  // name should have been undefined but its printing empty string
  console.log(name);
  var scope2 = function () {
    // name should have been undefined but its printing empty string
    console.log(name);
    var scope3 = function () {
      var name = 'Todd'; // locally scoped
    };
  };
  scope2();
};
scope1();
gman
  • 100,619
  • 31
  • 269
  • 393
SsNewbie
  • 257
  • 2
  • 8
  • 21
  • Wrap your code in `IIFE`=> `(function(){ /*your code*/ })()` and see the results..Name is property of global `window` object hence you are getting `""`. In `IIFE`, variables defined using `var` will refer to local variable..Not global... – Rayon Feb 29 '16 at 06:30
  • @RayonDabre However, this is bad practice to override the default (global) properties. – Bhojendra Rauniyar Feb 29 '16 at 06:37
  • That code would be *much* easier to follow if you indented it appropriately. – nnnnnn Feb 29 '16 at 06:40
  • No it is not bad practice to override default global properties. First he's not overriding it. Second new global properties are added all the time. Using a variable called *name* is probably one of the most common JavaScript variables out there next to *i* for index. – gman Feb 25 '17 at 08:00

3 Answers3

0

JavaScript has name built-in property. So, you'll get an empty string when you try to get name variable as it is pointing to window.name.

You need to use something else instead of name.

Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231
  • JavaScript does *not* have a built in *name* property. window has a `name` property but not all JavaScript environments have a window object. Example neither workers nor node.js have a window object., Also he doesn't *need* to use something other than `name`. He just needs to understand where it came from. Trying to use something that's not on the *window* object is nearly impossible because every new release new things are added to it. – gman Feb 25 '17 at 07:55
0

You need a proper understanding of lexical scoping, below is a brief and direct example to explain the concept and how it works:

lets say:

function(auto) {
   var vehicle = "bus";
   console.log(vehicle);

   function(innerAuto) {
     console.log(vehicle)
   }
   innerAuto();
}
auto();

So the inner function called innerAuto in this context gets an instruction to log the value for vehicle, which is nowhere to be found, immediately the function knows it should go to the outer scope to find it. i.e the JS runtime already knows that when executing this code there is no need to look inside the innerAuto function for a declaration of variable vehicle. So you wonder how does it knows this? It's because during the compile time it didn't see the variable declaration in the innerAuto function rather it saw it in the auto function. So lexical scoping is simply the compiled time scoping. For further information check MDN docs on lexical scoping and closures.

otoloye
  • 677
  • 7
  • 11
0

name is part of a list predefined names of implementation-dependent JavaScript objects. Therefore, it will not provide the reference error you would expect. Change the binding name to names to see the reference error expected.

You are also absolutely correct in your logical understanding of lexical scope. Lexical (or static) scope, provides for functions (or blocks) to view the bindings of their parent functions (or blocks). However, the parent functions (or blocks) do NOT have a view of the bindings created within their children. Global bindings, on the other hand, are visible to all.

Hope that helps, thanks!

P.V.C.
  • 1
  • 1