Can you change parameters on constant functions?

I’m confused why I’m able to reassign the value of the constant variable plantNeedsWater in the following code:

const plantNeedsWater = function(day) {
  if (day === 'Wednesday')
    {return true}
  else {
    return false;
  }
}

console.log(plantNeedsWater('Tuesday'));

console.log(plantNeedsWater('Wednesday'))

//outputs false, true

I was imagining that by calling the function, initially plantNeedsWater evaluates to a constant ‘falsey’ boolean, but then by calling the function a second time, you can change it to a truthy. Does this effectively destroy the original plantNeedsWater value by overwriting it?

5 Likes

The only thing constant is the name and the assigned function. Parameters are not in the same scope. That’s why we can run the function over and over with different inputs.

1 Like

Thanks for your reply. So to be clear, in the above code:

const plantNeedsWater = function(day){
}

is a function only, and not a variable declaration, right? Effectively the same as if I had typed:

function plantNeedsWater(day){
}

Can the function’s contents be changed later if I declared a function like:

let plantNeedsWater = function(day){
}

Through experimentation, I determined “yes” is the answer to the above questions. Thanks for your help!

No. The above is hoisted as a declared function; the preceding is hoisted as a variable, which expression will be caught on the next pass.

When we assign using = in our code, the right hand side does not get hoisted. That is why we call them function expressions; they appear on the right hand side of an equals sign. On that side they are values.

They can also appear in arguments to other functions, in which case we refer to them as a callback. Essentially when the return value of one function given the inputs becomes the argument value of another function, per chance with additional arguments (that may include the initial inputs in some way).

Hoisting and binding are two different things to keep aware of in JS.


 > (function () {
     return foo();
     function foo(day="Wednesday"){
       return day==="Wednesday" ? "Water me!" : "Don't water me!";
     }
   })()
<- "Water me!"
 >

 > (function () {
     return foo(arguments[0]);
     function foo(day="Wednesday"){
       return day==="Wednesday" ? "Water me!" : "Don't water me!";
     }
   })('Thursday')
<- "Don't water me!"
 > 

The binding is to the return (response) value of the expression. That’s the key. Only foo was ever hoisted. Least not to mention is the arguments object which may or may not be populated. The first value may be of some interest…


This tells us that hoisting occurs within functions, not just at the global level. Whatever isn’t hoisted is treated as a value on the second pass. Recall that expressions are values, and utilize that going forward.

6 Likes