Search and replace warning about out of scope use of variable

Search and replace warning about out of scope use of variable
0.0 0

#1

I have created variable upperCaseAfter in the main function than why I get the warning out of scope when I used it later by assigning to arr[i]?

  arr =str.split(" ");
  //to adjust upper or lower cases before we even replace the words and store it in new variable if after value has to be changed 
  
  for (var i=0; i<arr.length; i++) {   
    if(before[0]===before[0].toUpperCase()){
   var upperCaseAfter=after[0].toUpperCase() + after.substring(1);   
  }
        if (arr[i]===before &&  before[0]===before[0].toUpperCase()){          
      arr[i] = upperCaseAfter;      
        } else if(arr[i]==before && before[0]===before[0].toLowerCase()) {
          arr[i]=after;
        }      
        
      }
   
      str = arr.join(" "); 
  
 return str;
}
myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped");

#2

If I’m not mistaken your code actually works (even though it’s not ideal) and the issue is only a warning about a upperCaseAfter being potentially out of scope.

The problem here is because upperCaseAfter only gets defined (function-scoped) if the first letter in before is capitalised—meaning that it would not be defined if before is lowercase and it is possible later in your code that that upperCaseAfter is out of scope (since it’s used in the next if statement).

Without changing much of your code, and to do it slightly better, you can simply define upperCaseAfter before the for loop:

function myReplace(str, before, after) {
  // ...

  var upperCaseAfter;

  for (var i=0; i < arr.length; i++) {
    if (before[0] === before[0].toUpperCase()) {
      upperCaseAfter=after[0].toUpperCase() + after.substring(1);   
    }
    if (arr[i] === before &&  before[0] === before[0].toUpperCase()) {          
      arr[i] = upperCaseAfter;      
    } else if(arr[i] == before && before[0] === before[0].toLowerCase()) {
      arr[i]=after;
    }      
  }

  // ...
}

One thing that’s worth mentioning is that you have a lot of conditions that are the same or similar—that usually means that your logic, or at least the code, can be simplified. The two mains things that need to be done, according to your code, are:

  1. Check if after should be capitalised
  2. Replace the word specified by before in str with after

Using the logic in your code, one could simplify it to the following:

function myReplace(str, before, after) {
  // ...

  // Check if `before` is capitalised and capitalise after accordingly
  if (before[0] === before[0].toUpperCase()) {
    after = after[0].toUpperCase() + after.substring(1);   
  }

  // Replace before in str with after
  for (var i = 0; i < arr.length; i++) {
    if (arr[i] === before) {          
      arr[i] = after;
    }      
  }

  // ...
}

Also, an assignment statement without a variable declaration keyword is declared to the global scope, consider the following examples:

function fn() {
  nya = 'nya';
}

fn()
console.log(nya); // "nya"
function fn() {
  var nya = 'nya';
}

fn()
console.log(nya); // ReferenceError: nya is not defined

#3

@honmanyau I just declared the variable upperCaseAfter before the for loop with var keyword and it took the warning away !! thanks for your help !!