code: private void visitBlockScopedName(NodeTraversal t, Node decl, Node nameNode) {
      Scope scope = t.getScope();
      Node parent = decl.getParent();
      // Normalize "let x;" to "let x = undefined;" if in a loop, since we later convert x
      // to be $jscomp$loop$0.x and want to reset the property to undefined every loop iteration.
      if ((decl.isLet() || decl.isConst())
          && !nameNode.hasChildren()
          && (parent == null || !parent.isForIn())
          && inLoop(decl)) {
        Node undefined = createUndefinedNode().srcref(nameNode);
        nameNode.addChildToFront(undefined);
        compiler.reportChangeToEnclosingScope(undefined);
      }
  
      String oldName = nameNode.getString();
      Scope hoistScope = scope.getClosestHoistScope();
      if (scope != hoistScope) {
        String newName = oldName;
        if (hoistScope.hasSlot(oldName) || undeclaredNames.contains(oldName)) {
          do {
            newName = oldName + "$" + compiler.getUniqueNameIdSupplier().get();
          } while (hoistScope.hasSlot(newName));
          nameNode.setString(newName);
          compiler.reportChangeToEnclosingScope(nameNode);
          Node scopeRoot = scope.getRootNode();
          renameTable.put(scopeRoot, oldName, newName);
        }
        Var oldVar = scope.getVar(oldName);
        scope.undeclare(oldVar);
        hoistScope.declare(newName, nameNode, oldVar.input);
      }
    }
docs: Renames block-scoped declarations that shadow a variable in an outer scope
  
  <p>Also normalizes declarations with no initializer in a loop to be initialized to undefined.