javascript에서의 뻘짓 #1의 연장선인 뻘짓입니다.
const f = (function() {
const f1 = function() { console.log(1); }
const f2 = function() { f1(); }
return {f1: f1, f2: f2}
})()
f.f1 = function() { console.log(2); }
f.f1()
f.f2()
2
1
위의 코드를 실행 시켰을 때 글쓴이는 2가지 의문점이 생겼습니다.
(전 Javascript를 사용 할 줄 안다고 하면 안될 것 같아요)
- f1을 const로 선언했는데, f.f1에 재할당을 하는데 왜 오류가 발생하지 않지?
- f.f1에 재할당한 후 f.f1()에서는 재할당한 함수가 정상적으로 호출되는데, 왜 f2()에서 f1()을 호출할 때는 반영이 안되지?
고민을 해봅니다..
1) IIFE는 const로 선언된 f1과 f2를 return하고 이를 f에 저장한다.
2) f는 const로 선언 된 f1과 f2를 가지고 있는 객체이다.
3) f의 f1에 재할당하였다.
4) f1()를 호출하였다.
5) f2()를 호출하였다.
우선, 2)단계, const로 선언한 변수인 f1에 재할당을 하였는데 왜 오류가 발생하지 않지?
이부분에 대해서 한참을 고민했습니다.
javascript에서의 객체는 key와 value로 이루어져 있는 속성을 가지고 있고,
여기서 key는 f1, k2, 그리고 value는 각각 f1,f2
객체의 속성은 마침표 또는 []형태로 접근.
[]는 배열이랑 비슷하네..배열..? 윙..배열?…참조…?!!!
아하!! f1이 f1이 아닐 수도 있겠구나! (즉, f.f1은 const f1를 복사한 값입니다.)
만약 복사하지 않았다면 함수 내부에서 선언한 변수가 함수 종료 시까지 메모리에 남아 있어 접근이 가능 할 리가 없습니다.(=클로저를 통한 은닉화)
이제 의문점이 모두 해결 되었습니다.
- f1을 const로 선언했는데, f.f1에 재할당을 하는데 왜 오류가 발생하지 않지?
f.f1은 IIFE 내부에서 선언된 f1의 값을 복사한 변수이므로 재할당이 가능
- f.f1에 재할당한 후 f.f1()에서는 재할당한 함수가 정상적으로 호출되는데, 왜 f2()에서 f1()을 호출할 때는 반영이 안되지?
IIFE의 f2()는 상수화된 변수 f1()를 호출하며, 이 때 f1()은 IIFE 선언 시 정의 된 f1()이다 IIFE 종료 시 f1()에 재할당하였어도, IIFE 호출 시점에 f2()는 정의된 f1()을 호출하므로 재할당된 f1()이 반영되지 않는다.
IIFE와 Closure에 대해 정확히 이해하고 있었으면 발생하지 않았을 뻘짓이었습니다.