in Javascript, in the return statement of a function, I cannot explicitly declare a variable like that return let text = "hello world!"
, so far so good
But also, when I declare a variable I can do it without a keyword like var
, let
or const
, it's what w3school call an automatically declared variable : https://www.w3schools.com/js/js_variables.asp like that : newVariable = "I'm a new variable"
instead of that : let newVariable = "I'm a new variable"
or that : const newVariable = "I'm a new const variable"
Now, I noticed that if I use an automatically declared variable in a return statement, it seems to have declared the variable outside of the function scope :
let myP = document.getElementById("output");
function printInfos(name, age) {
return info = `${name} is ${age}`;
}
printInfos("john", 4);
myP.textContent = info; // output "john is 4"
<p id="output"></p>
info = 'john is 4'
info
I already consider automatically declared variables as bad practice, but in most cases I'm not even sure why other than readability (when I see the variable without keyword I wrongly assume it has been declared earlier), since I can treat them just like a declaration with let
But the case of a declaration inside a return statement confuses me since it allows me to do something I cannot do when I "properly" declare the variable, it feels like a bug
so what is it ? Can I use it ?
You can create variables this way only in non-strict mode (which is kind of deprecated).
But it's not creating a new variable but assigning a value to a property of the global object (window
in our case). So it could be considered that you cannot create a real new variable this way.
That's also bad because you can override any intrinsic or previous values assigned to window
.
Plus you gain nothing by introducing a new variable in the return statement. Just return.
You assign your function's result to the output element through a intermediate variable. Seems a waste of efforts also. Just assign directly.
You could argue that you cache the result but you can create a memoized function for that (the last snippet)
let myP = document.getElementById("output");
function printInfos(name, age) {
info = `${name} is ${age}`;
// it's now a property of window
console.log(window.info);
return `${name} is ${age}`;
}
myP.textContent = printInfos("john", 4);
<p id="output"></p>
In the strict mode you get an error:
'use strict';
let myP = document.getElementById("output");
function printInfos(name, age) {
info = `${name} is ${age}`;
console.log(window.info);
return `${name} is ${age}`;
}
printInfos("john", 4);
myP.textContent = info; // output "john is 4"
<p id="output"></p>
There are several methods that you could use to avoid declaring a new variable with const/let/var
, for example through function arguments (the example isn't real life cases):
let myP = document.getElementById("output");
function printInfos(name, age, info = null) {
info ??= [name, age];
return info.join(' is ');
}
myP.textContent = printInfos("john", 4);
<p id="output"></p>
A memoized version (here we use an argument + a closure to avoid variable declaration + hide the argument):
let myP = document.getElementById("output");
const printInfos = (cache => (name, age) => cache[`${name}%${age}`] ??= `${name} is ${age}`)({});
myP.textContent = printInfos("john", 4);
<p id="output"></p>