본문 바로가기

code-states

[code-states][we-win] 2일차 - 어린이날 독학, Hoisting, Closure

어린이날 덕분에, 일단 10문제 완료! ​

 

일단 주말을 활용해서, 문제는 다 풀긴 풀었습니다

다만 하나 아쉬운 점이 하나 있었는데

문제를 너무 조건문 떡칠로 풀었다는 점 입니다

물론 조건문을 배우는 단계이긴 하지만

아무리 내가 봐도, 이건 좀 선을 넘은 거 같다는 생각이 들었어요

이를 어떻게 간단하게 해결할 수 있는 방법이 없을까 생각을 해 보던 도중

'왜인지 모르게 해결 방법의 실마리를 줄 거 같다' 는 생각으로 알아보게 된 건 세 개

1. Hoisting : 선언을 하지 않아도, 알아서 끌어올려주는 JS 의 특성

2. JS에서의 함수 선언식과 표현식 : 함수 선언식은 hoisting 이 가능하나, 표현식은 그렇지 않아요

3. Closure 와 Lexical Scoping : 함수 내의 함수

 


 

1. Hoisting

https://developer.mozilla.org/ko/docs/Glossary/Hoisting

 

Hoisting

호이스팅(hoisting)은 ECMAScript® 2015 언어 명세 및 그 이전 표준 명세에서 사용된 적이 없는 용어입니다. 호이스팅은 JavaScript에서 실행 콘텍스트(특히 생성 및 실행 단계)가 어떻게 동작하는가에 대한 일반적인 생각으로 여겨집니다. 하지만 호이스팅은 오해로 이어질 수 있습니다.

developer.mozilla.org

* 앞으로 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. 함수 선언식

 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/function#Function_declaration_hoisting

 

함수 선언

함수 선언(function declaration)은 지정된 매개변수(parameter)를 갖는 함수를 정의합니다.

developer.mozilla.org

//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

 

함수 표현식

function 키워드는 어떤 표현식(expression) 내에서 함수를 정의하는 데 사용될 수 있습니다.

developer.mozilla.org

그러나 함수 표현식은 조금 다릅니다

일단 hoisting 이 불가능합니다

자바스크립트에서 함수 표현식은 함수 선언과는 달리 끌어올려지지 않습니다.

함수 표현식을 정의하기 전에는 사용할 수 없습니다.

mozilla docs

아까 선언식으로 구현했던 dogOrCat 함수를

한 번 표현식으로 구현해 볼까요?

//함수표현식으로 구현한 함수
var dogOrCat = function(animal) { 
	console.log(animal); 
} 

dogOrCat('dog'); 
//이제 이런 경우, dog 을 출력하게 되겠죠

hoisting 이 되는지도 한 번 확인해 보겠습니다

google chrome dev tools console  에 돌려본 결과

 

네, 당연하게도 되지 않습니다

단순히 말해서 hoisting 의 가능/불가능이 가장 큰 차이점이었군요

그렇다면 대망의 마지막 단원, Closure 로 가볼까요


3. Closure, 그리고 Lexical scoping

https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Closures

 

클로저

클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다. 클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야 한다.

developer.mozilla.org

클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다.

클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야 한다.

mozilla docs

lexical scoping 을 먼저 이해한 후에야 closure 를 이해할 수 있다고 하는...데

어, 잠깐만! lexical 은 무슨 말일까요

the meaning of 'lexical' from cambridge dictionary ​

 

별 의미는 없이, '언어와 관련이 된' 이라는 형용사군요

그렇다면 lexical scoping 은, 'JS 라는 언어의 범위를 잡아주는 과정' 이라고 할 수 있겠네요

 


 

3-1. Lexiclal scoping

자 이제, mozilla 가 예시로 제공해 준 코드와 설명을 같이 봐 볼까요

function init() {
  var name = "Mozilla"; // name은 init에 의해 생성된 지역 변수이다.
  function displayName() { // displayName() 은 내부 함수이며, 클로저다.
    alert(name); // 부모 함수에서 선언된 변수를 사용한다.
  }
  displayName();
}
init();

나름대로 이해해 본 lexical scoping

 

init()은 지역 변수 name과 함수 displayName()을 생성한다.

displayName()은 init() 안에 정의된 내부 함수이며 init() 함수 본문에서만 사용할 수 있다.

여기서 주의할 점은 displayName() 내부엔 자신만의 지역 변수가 없다는 점이다.

그런데 함수 내부에서 외부 함수의 변수에 접근할 수 있기 때문에

displayName() 역시 부모 함수 init()에서 선언된 변수 name에 접근할 수 있다.

만약 displayName()가 자신만의 name변수를 가지고 있었다면, name대신 this.name을 사용했을 것이다.

mozilla docs

 

다시 말해서 부모 함수 밑의 자식 함수는 부모함수와 변수를 공유한다

라는 내용 이군요

 


 

 

Clousre 문서입니다

옆의 남아있는 스크롤바가 보이시나요?

후, 이 이후에도 가야 할 길은 어마어마하게 머네요

 

머리가 살살 뜨거워 집니다 

이럴 땐 일단 세이브 버튼이죠

경험 상 쎄할 때는 일단 Ctrl(Cmd) + S 를 눌러주는 것이 제 수칙입니다

 

일단은 오늘은 여기까지 공부한 뒤 깃발을 꽂고 나서

배운 내용들을 통해 오늘의 목적인 코드 리팩토링을 해 볼까요?


 

 

이번의 저의 목적입니다!

그리고 나서 열심히 시도한 결과

아 ㅋㅋ

네 깔끔하게 실패했습니다

원래 가위바위보도 삼세판이라잖아요...? ^^

두 번이나 더 도전할 수 있고, 시작이 반이니깐

50% 이해했다고 치고 오늘은 퇴진하겠습니다

뭔가 허전하지만, 반박은 받지 않겠습니다!!!!!

그렇지만, 계속되는 저의 도전을 지켜봐주세요!!!! 

 

도전은 계속된다.