0

I am learning javascript hoisting feature, and find the following codes are really confusing:

var a = 1;
function b() {
    a = 10;
    return;
    function a() {}
}
b();
alert(a);

The output is 1. As far as I know, because of hoisting, the codes above are equivalent to

var a;
function b() {      
    function a() {}
    a=10;
    return;
}
a=1;
b();
alert(a);

What happens when a function and a variable has the same name a?

chrisTina
  • 2,298
  • 9
  • 40
  • 74
  • 4
    Possible duplicate of [Javascript function scoping and hoisting](http://stackoverflow.com/questions/7506844/javascript-function-scoping-and-hoisting) – Hunan Rostomyan Dec 06 '15 at 01:00

5 Answers5

1

Within b, a local variable a is first set to a function, and then the value 10. The outer variable a remains unaffected, since it is shadowed by the local variable a within b. Perhaps this roughly equivalent code will help illustrate:

var a = 1;
function b() {
    var a;
    a = function a() { };
    a = 10;
    return;
}
b(); // Basically a no-op
alert(a);
Asad Saeeduddin
  • 46,193
  • 6
  • 90
  • 139
1

What happens when a function and a variable has the same name a?

Nothing special. One assignment to a overwrites the other because they are both values.

console.log(a) // a points to a function here
var a = 4
console.log(a) // a points to 4 here
function a() {}
console.log(a) // a also points to 4 here!

By the way, a variable in a scope outside of a function can only be modified by that function if the variable isn't local to the function.

var a = 4
;(function() {
    a = 5
})() // <-- Immediately calling the function here
console.log(a) // a is now 5
;(function() {
    a = 6
    var a
})()
// a is still 5 because in the previous function,
// a was local to the function's scope
console.log(a)

Function parameters are implicitly local to the variable, so they automatically "shadow" globals that share the same name.

Shashank
  • 13,713
  • 5
  • 37
  • 63
  • why the first `console.log(a)` equals 5? In `js`, a function creates a new scrope, then the definition `a=5` should not be in effect outside the `function` scrope, so I think the output should still be `4`. – chrisTina Dec 06 '15 at 01:20
  • @byteBiter All functions do have their own local scope. :) But for all variables that are *not* in local scope (i.e. variables that are not `var`s or parameters or function declarations), the function looks up the value of `a` in its parent scope (i.e. the scope in which the function was created), and if its not there then it goes to the parent of the parent and so on. This concept is known as lexical scope and it's a powerful language feature that makes closures implicit and easy to work with. – Shashank Dec 06 '15 at 01:22
0

The function:

function b() {
    a = 10;
    return;
    function a() {}
}

Is basically the same thing as this, due to hoisting pushing the function to the top of its scope:

function b() {      
    function a() {}
    a = 10;
    return;
}

It is also important to note that function a() {} is the same as writing var a = function() {}. So now, we have something like this:

function b() {      
    var a = function() {}
    a = 10;
    return;
}

Since inside of the function b() a variable named a was declared, b() is only working with and changing that a within its local scope, so the a that is declared outside of the function b() is left untouched.

Nick Zuber
  • 5,467
  • 3
  • 24
  • 48
0

If we omit function a() {}, then the value of the global a will be assigned from inside the function b()

var a = 1;
function b() {
  a = 10; 
}
b();
console.log(a); // 10

Using function a() {} inside the function b() will have the same effect as if we declared var a=10; This will limit the scope of a to inside the function b() and won't bleed outside its scope.

var a = 1;
function b() {
  var a = 10; 
}
b();
console.log(a); // 1

Here is an easy read article on Hoisting: https://medium.com/@bouguerra_70679/hoisting-464979b60282

0

What happens when a function and a variable has the same name a?

In JavaScript, functions are first-class objects, because they can have properties and methods just like any other object.

(What distinguishes them from other objects is that functions can be called.)

In other words, functions are defined as variables of type function, and can be passed to other functions, stored in arrays, etc.

So when a function and a variable has the same name a, there could be some conflict, as in your example:

var a;
function b() {      
    function a() {} // variable a of type function shadows variable a in the outer scope
    a=10; // variable a defined in the inner scope is now of number, instead of function any more
    return;
}
a=1;
b();
alert(a); // 1
Yuci
  • 27,235
  • 10
  • 114
  • 113