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'));