일단 주말을 활용해서, 문제는 다 풀긴 풀었습니다
다만 하나 아쉬운 점이 하나 있었는데
문제를 너무 조건문 떡칠로 풀었다는 점 입니다
물론 조건문을 배우는 단계이긴 하지만
아무리 내가 봐도, 이건 좀 선을 넘은 거 같다는 생각이 들었어요
이를 어떻게 간단하게 해결할 수 있는 방법이 없을까 생각을 해 보던 도중
'왜인지 모르게 해결 방법의 실마리를 줄 거 같다' 는 생각으로 알아보게 된 건 세 개
1. Hoisting : 선언을 하지 않아도, 알아서 끌어올려주는 JS 의 특성
2. JS에서의 함수 선언식과 표현식 : 함수 선언식은 hoisting 이 가능하나, 표현식은 그렇지 않아요
3. Closure 와 Lexical Scoping : 함수 내의 함수
1. Hoisting
https://developer.mozilla.org/ko/docs/Glossary/Hoisting
* 앞으로 JS에 관해선 웹의 Big Boy, mozilla 의 문서를 official docs 에 준하게 참고할 예정입니다
the meaning of 'hoist' from cambridge dictionary
hoist 란, '어떤 무거운 것을 기계나 줄을 통해 끌어올리는 행위' 를 의미하는 단어입니다
hoisting 은 그렇다면, 무언가를 끌어올리는 행위를 의미하겠죠
mozilla 에서의 hoisting 에 대한 설명
함수를 호출하고, 함수를 활용하는 것이 일반적입니다만
JS 의 경우는 함수를 먼저 활용하고, 그 다음에 호출을 해도 무방합니다
아... 그래서 함수를 끌어올려 위로 올려준다는 느낌으로, hoisting 이라고 한 거구나, 싶기도 하네요
그렇지만 꼭 함수에만 국한되는 건 아니군요
Hoisting은 다른 데이터 타입 및 변수와도 잘 작동합니다.
변수는 선언하기 전에 초기화하여 사용될 수 있습니다.
그러나 초기화 없이는 사용할 수 없습니다.
mozilla docs
함수 뿐만이 아닌 다른 데이터 타입에도 hoisting 을 사용할 수 있다고 하네요
사실 먼저 hoisting 을 찾아보려고 한 건 아니었습니다
JS의 함수 선언식과 함수 표현식의 연관 키워드로 hoisting 이 나와서 찾게 되었거든요
그러면 함수 선언식과 표현식은 어째서 hoisting 과 연관이 있게 된걸까요?
2. JS에서의 함수 선언식과 표현식
2-1. 함수 선언식
//hoisting test code
dogOrCat('dog')
function dogOrCat(animal) {
console.log(animal)
}
//마찬가지로, dog 가 출력됩니다
//함수를 선언하지 않고 먼저 들어와 줘도, hoisting 이 되어 함수 안의 code 들이 작동됩니다
네, 일반적인 경우입니다
function, function name, parameter 와 내부의 code 를 통해 실행해주는
우리가 흔히 아는 함수이죠
그리고 이 경우는 hoisting 이 가능합니다
분명 함수 선언보다, 함수 호출을 먼저 하였음에도 불구하고
dog 가 console 창에 잘 출력되는 모습을 보실 수 있습니다
2-2. 함수 표현식
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/function
그러나 함수 표현식은 조금 다릅니다
일단 hoisting 이 불가능합니다
자바스크립트에서 함수 표현식은 함수 선언과는 달리 끌어올려지지 않습니다.
함수 표현식을 정의하기 전에는 사용할 수 없습니다.
mozilla docs
아까 선언식으로 구현했던 dogOrCat 함수를
한 번 표현식으로 구현해 볼까요?
//함수표현식으로 구현한 함수
var dogOrCat = function(animal) {
console.log(animal);
}
dogOrCat('dog');
//이제 이런 경우, dog 을 출력하게 되겠죠
hoisting 이 되는지도 한 번 확인해 보겠습니다
네, 당연하게도 되지 않습니다
단순히 말해서 hoisting 의 가능/불가능이 가장 큰 차이점이었군요
그렇다면 대망의 마지막 단원, Closure 로 가볼까요
3. Closure, 그리고 Lexical scoping
https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Closures
클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다.
클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야 한다.
mozilla docs
lexical scoping 을 먼저 이해한 후에야 closure 를 이해할 수 있다고 하는...데
어, 잠깐만! lexical 은 무슨 말일까요
별 의미는 없이, '언어와 관련이 된' 이라는 형용사군요
그렇다면 lexical scoping 은, 'JS 라는 언어의 범위를 잡아주는 과정' 이라고 할 수 있겠네요
3-1. Lexiclal scoping
자 이제, mozilla 가 예시로 제공해 준 코드와 설명을 같이 봐 볼까요
function init() {
var name = "Mozilla"; // name은 init에 의해 생성된 지역 변수이다.
function displayName() { // displayName() 은 내부 함수이며, 클로저다.
alert(name); // 부모 함수에서 선언된 변수를 사용한다.
}
displayName();
}
init();
init()은 지역 변수 name과 함수 displayName()을 생성한다.
displayName()은 init() 안에 정의된 내부 함수이며 init() 함수 본문에서만 사용할 수 있다.
여기서 주의할 점은 displayName() 내부엔 자신만의 지역 변수가 없다는 점이다.
그런데 함수 내부에서 외부 함수의 변수에 접근할 수 있기 때문에
displayName() 역시 부모 함수 init()에서 선언된 변수 name에 접근할 수 있다.
만약 displayName()가 자신만의 name변수를 가지고 있었다면, name대신 this.name을 사용했을 것이다.
mozilla docs
다시 말해서 부모 함수 밑의 자식 함수는 부모함수와 변수를 공유한다
라는 내용 이군요
Clousre 문서입니다
옆의 남아있는 스크롤바가 보이시나요?
후, 이 이후에도 가야 할 길은 어마어마하게 머네요
머리가 살살 뜨거워 집니다
이럴 땐 일단 세이브 버튼이죠
경험 상 쎄할 때는 일단 Ctrl(Cmd) + S 를 눌러주는 것이 제 수칙입니다
일단은 오늘은 여기까지 공부한 뒤 깃발을 꽂고 나서
배운 내용들을 통해 오늘의 목적인 코드 리팩토링을 해 볼까요?
이번의 저의 목적입니다!
그리고 나서 열심히 시도한 결과
네 깔끔하게 실패했습니다
원래 가위바위보도 삼세판이라잖아요...? ^^
두 번이나 더 도전할 수 있고, 시작이 반이니깐
50% 이해했다고 치고 오늘은 퇴진하겠습니다
뭔가 허전하지만, 반박은 받지 않겠습니다!!!!!
그렇지만, 계속되는 저의 도전을 지켜봐주세요!!!!