Reputation: 7051
I'm wondering why I'm getting an error of "x variable not defined" inside a function that uses a variable that is declared on the same line that I execute the function. Here is the snippet (ES6)
let timeout = resetTimeout();
function resetTimeout () { timeout = 0; return timeout }
why is the scoping acting here? the variable is being defined BEFORE the function definition, so, why?
EDIT To clarify the question, I know that it will work with var. I already read about the scoping of let and const, and I'm unable to understand why this does not works as I expect. What I'm looking for is for an explanation, not a solution.
Upvotes: 1
Views: 1848
Reputation: 311
The key concept here is "hoisting."
Every variable declared with 'var' is first hoisted, then it will be assigned; With 'let' it is different, it will not hoist the variable, so first js will evaluale the right side of the assigment; at that point the variable is not defined yet! The next, slightly different code works with let:
let timeout
timeout = resetTimeout()
function resetTimeout () { timeout = 0; return timeout }
Note: A variable declared by let or const has a so-called temporal dead zone (TDZ) (see http://2ality.com/2015/02/es6-scoping.html#the_global_object)
Upvotes: 0
Reputation: 129
Taking into consideration your update and this guy's answer, I would like to state that you don't need to rename your variable. Since let works only on one layer and do not go deeper into scope, you can declare new variable timeout within the function.
let timeout = resetTimeout();
function resetTimeout () { let timeout = 0; return timeout; }
Hope that helped a bit. Sorry for previous answer.
Upvotes: -1
Reputation: 2688
You are creating a variable using let and immediately assigning a function's return value to it. This is okay.
The problem is inside the function. Without specifying the type of the variable timeout (= 0) you are dealing with the same timeout defined using let before. So there is a circular reference. Let's see how your code executed :
1 - First line calls the function, timeout is created in the scope but it's value undefined yet.
2 - In the function body the 'timeout' is tried to be set to 0. Since it is in the scope, js cannot create a global variable (which normally does) and assignment will throw an error.
Fix? If you intended the timeout inside the function block to be local, just rename it.
Using let is just fine.
Upvotes: 2