I know there are different ways of declaring a function in JavaScript. Specifically my doubt is with the "standard" way of declaring a function, let's say we have the next function:
function salute(name) {
let phrase = `Hello ${name}, nice to meet you`;
document.write(phrase + `<br/>`);
}
(I know document.write()
ain't a good practice, but I'm just using it to test code).
Now, it is possible to assign another function to salute
, e.g.:
salute = function(){
document.write(`This is a different function <br/>`);
}
Is the original salute
function declare like a var variable/object? I know one can redeclare a variable within the same scope if declared as var, e.g.:
var aVariable = 10;
var aVariable = 11;
But this doesn't work with let and const as explained here: Difference between var and let
Continuing with the original code, I realized I can redeclare salute
using var:
var salute = function(){
document.write(`This is a different function <br/>`);
}
But I can't do the same with let or const. This made me conclude that the "standard" way of declaring a function has an implicit var scope. Am I right?
This largely depends on what you consider "standard" to which I would say the answer is yes and no.
On the top level environment of a script, your function behaves like a variable declaration would (e.g. with var
). That means you could write the same function declaration twice even and no error would be thrown out. The last declaration would override the previous one.
function test(){
console.log(1);
}
function test(){
console.log(2);
}
test(); //2
Inside a function definition, the behavior is pretty much the same:
(function nested(){
function test(){
console.log(1);
}
function test(){
console.log(2);
}
test(); //2
})()
Notice this could even be strict
code:
(function nested(){
'use strict';
function test(){
console.log(1);
}
function test(){
console.log(2);
}
test(); //2
})()
However, once we start using blocks AND strict
code... things start to change...
'use strict';
{
test();
function test(){
console.log(1);
}
function test(){
console.log(2);
} //SyntaxError
}
Also, unlike script top level environment, modules also behave like blocks on strict
mode (as far function declaration goes).
function test(){
console.log(1);
}
function test(){
console.log(2);
}
test(); //SyntaxError
It's still not exactly as let
since functions still get hoisted (let
variables do not get initialized until they reach the declaration) and it's definitely not immutable as a const
variable, since you could still overwrite the functions.
'use strict';
{
test = function(){
console.log(2);
}
test(); //2
function test(){
console.log(1);
}
}