Search code examples
javascriptreturnreturn-value

is it good practice to create a variable in a return in javascript?


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>

What I suppose is happening is the following :

  1. the function return the whole expression after expansion info = 'john is 4'
  2. then it is evaluated as an automatically declared variable info

But I wonder how much it is good practice or not ?

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 ?


Solution

  • 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>