2

I have trouble understanding the following code snippet, which is supposed to calculate the avarage length of the specified string:

const str = 'This sentence will be used to calculate average word length';
const averageWordLength = str => {
   if(!str.includes(' ')){
      return str.length;
   };
   const { length: strLen } = str;
   const { length: numWords } = str.split(' ');
   const average = (strLen - numWords + 1) / numWords;
   return average.toFixed(2);
};
console.log(averageWordLength(str));
console.log(averageWordLength('test test'));

What is str? Is str a global variable, which is consequently used in a function? A function itself? A parameter we pass to a function? I know about arrow functions and I suspect there is one, but these overlaps confuse me. Thank you in advance for any clarification.

Bob
  • 23
  • 3
  • 1
    Which `str`? There are two. – Quentin Apr 04 '21 at 23:11
  • `str` refers to a constant variable outside of the arrow function `averageWordLength` and to a parameter inside of it. See [the documentation of arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) and [how functions work in general](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions). See also [What is the scope of variables in JavaScript?](https://stackoverflow.com/q/500431/4642212). – Sebastian Simon Apr 04 '21 at 23:11
  • @Quentin That was the question) Because I see only 3 letters and don't know which variable refers to what – Bob Apr 04 '21 at 23:18
  • @SebastianSimon Thanks, I'll check it out) – Bob Apr 04 '21 at 23:21
  • Does this answer your question? [What is the scope of variables in JavaScript?](https://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript) – Heretic Monkey Apr 04 '21 at 23:28

2 Answers2

1

Because you have used str as both a variable at the top, and as a parameter name in the function, the value of str will be different depending on if you are in the function's scope or not.

This is called Variable Shadowing. From wikipedia:

In computer programming, variable shadowing occurs when a variable declared within a certain scope (decision block, method, or inner class) has the same name as a variable declared in an outer scope. At the level of identifiers (names, rather than variables), this is known as name masking. This outer variable is said to be shadowed by the inner variable, while the inner identifier is said to mask the outer identifier. This can lead to confusion, as it may be unclear which variable subsequent uses of the shadowed variable name refer to, which depends on the name resolution rules of the language.

Generally it is recommended to avoid shadowing, as it can make it hard to remember what scope your in and what value you expect a variable to have.


Lets annotate the example code to show the scopes and which var is which:

/* Top level scope */
const str/* outer */ = 'This sentence will be used to calculate average word length';
/*                        ↓↓↓ new scope is created here with a new function */
const averageWordLength = str/* inner */ => {
  /* function scope */
   if(!str/* inner */.includes(' ')){
      return str/* inner */.length;
   };
   const { length: strLen } = str/* inner */;
   const { length: numWords } = str/* inner */.split(' ');
   const average = (strLen - numWords + 1) / numWords;
   return average.toFixed(2);
};
/* Top level scope */
console.log(averageWordLength(str/* outer */));
console.log(averageWordLength('test test'));

coagmano
  • 5,542
  • 1
  • 28
  • 41
-1

In case you want to deal with the white spaces:

function avgerageWordLength(str){
  let s = str.trim().split(/(?:\s|\n)+/), n = 0;
  for(let w of s){
    n += w.length;
  }
  return n/s.length;
}
console.log(avgerageWordLength('This sentence will be used to calculate average word length'));
StackSlave
  • 10,613
  • 2
  • 18
  • 35