⭕️ displayName() 이냐, return displayName; 이냐의 차이 ❗️
▶️ displayName() (displayName함수를 실행) → 부모함수만 치면 정상 작동 
▶️ return displayName; (displayName함수를 리턴) → 밑에서 변수 설정해줘야 정상 작동
function init() {
      var name = "Mozilla"; // name은 init에 의해 생성된 지역 변수이다.
      function displayName() { // displayName() 은 내부 함수이며, 클로저다.
        alert(name); // 부모 함수에서 선언된 변수를 사용한다.
      }
      displayName();
    }
// init() 하면 실행됨
☑️ 여기서 콘솔에, makeFunc() 치면
f displayName() {
 alert(name);
 }
이렇게 안에 closure함수가 숨어있다는 내용이 뜸
☑️ 여기서 콘솔에, displayName() 이나 displayName 을 치면 Uncaught ReferenceError: displayName is not defined 
✅ displayName이 closure 함수라서 숨겨져 있는 것임.
☑️ 여기서 주의할 점은 displayName() 내부엔 자신만의 지역 변수가 없다는 점이다. 
함수 내부에서 외부 함수의 변수에 접근할 수 있기 때문에 displayName() 역시 부모 함수 init()에서 선언된 변수 name에 접근할 수 있다. 
만약 displayName()가 자신만의 name변수를 가지고 있었다면, name대신 this.name을 사용했을 것이다.
☑️ 얘는 그냥 콘솔에 init() 치면 alert팝업으로 Mozilla가 뜨는 displayName() 실행된다.

function makeFunc() {
      var name = "Mozilla";
      function displayName() {
        alert(name);
      }
      return displayName;
    }
// let 변수 = makeFunc();
// 변수(); 까지 해줘야 makeFunc 정상실행
☑️ 여기서 콘솔에, makeFunc() 치면
f displayName() {
 alert(name);
 }
이렇게 안에 closure함수가 숨어있다는 내용이 뜸
   ☑️ 여기서 콘솔에, displayName() 이나 displayName 을 치면 Uncaught ReferenceError: displayName is not defined 
✅ displayName이 closure 함수라서 숨겨져 있는 것임.
✅ makeFunc() 함수에 변수를 설정해줘야 정상작동 ❗️
밑에 이렇게 쓰기:
let 변수 = makeFunc();
변수();
→ 변수() 해야 alert팝업으로 Mozilla가 뜨는 displayName() 실행된다.
function makeAdder(x) {
      var y = 1;
      return function(z) {
        y = 100;
        return x + y + z;
      };
    }
let add2= makeAdder(2)         
console.log(add2(3))         
add2(3) -> makeAdder(2) 안의 함수에 인자 3을 넣은 것이다. (add2는 클로저이다)
즉, makeAdder(2)의 x,y 값을 그대로 가지고, 
makeAdder함수가 return하는 function(z) 에 인자 3을 넣는다.
따라서, add2(3)은 2 + 100 + 3 = 105 가 된다.