The Superior Man
The Superior Man

Reputation: 23

Basic JavaScript, why is this function not passing the parameter

I'm trying to learn JavaScript coming from C#. I wrote this simple code but for some reason, the parameter is not being passed to the setTimeout function.

function displayName(name) {
    console.log(`Name is ${ name }`);
}

function login(name) {
    // The argument 'name' is not being passed from the login function to the setTimeout !!
    setTimeout(name =>{
        displayName(name)
    }, 2000);
}

login("Satoshi")

I expect the output to be: Name is Satoshi
Instead I get: Name is undefined

Where am I going wrong? There's clearly something I am not understanding about JavaScript parameters and scope.

Upvotes: 2

Views: 192

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074038

The argument 'name' is not being passed from the login function to the setTimeout !!

That's because you're shadowing the login name parameter with the parameter to your arrow function. A parameter name in a function parameter list is similar to a variable declaration within the function body, so your original code has an outer name (in login) and a separate inner one (in the arrow function). The innermost one is the one that gets used when you use the name of the parameter (or variable).

Replace name with () in the arrow function so it doesn't declare its own name parameter; then it will close over the name parameter in login:

function login(name) {
    setTimeout(() =>{
// −−−−−−−−−−−−^^
        displayName(name);
    }, 2000);
}

By default, setTimeout on browsers doesn't call the function you give it with any arguments, so the name parameter in the arrow function in your original code would always have the value undefined.

In some situations you may want setTimeout to pass an argument or arguments to the timer callback when calling it, which you do by passing those after the timeout interval, like this:

function login(name) {
    setTimeout(innerName =>{
//             ^^^^^^^^^−−−−−−−− the arrow function's parameter
        displayName(innerName);
//                  ^^^^^^^^^−−− using the arrow function's parameter's value
    }, 2000, name);
//           ^^^^−−−−−−−−−−−−−−− `login`'s `name`
}

But there's no need for that in your example.

Upvotes: 7

Related Questions