일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 데이터분석
- rnn
- 컴퓨터비전
- 순환신경망
- CSS
- JSP
- 컴퓨터구조
- 자바스크립트
- SQL
- JSP/Servlet
- 중학수학
- JDBC
- 정보처리기사필기
- 정보처리기사실기
- html/css
- 자바
- 상속
- 데이터베이스
- 딥러닝
- 중학1-1
- 파이썬
- 개발일기
- 머신러닝
- 자바 실습
- 혼공머신
- 디버깅
- ChatGPT
- 연습문제
- 자바스크립트심화
- c언어
- Today
- Total
클라이언트/ 서버/ 엔지니어 "게임 개발자"를 향한 매일의 공부일지
실행 컨텍스트 3 - 실행 컨텐스트 본문
어제도 공부를 얼마 하지 못하고 일찍 취침했다. 그리고 다음날 새벽 1시 10분에 일어나 공부를 시작해 본다. 새벽에 일찍 일어나 공부할 수 있어서 정말 기뻤다. 어제는 가족들과 오랜만에 식사도 하며 오손도손 이야기도 나눌 수 있어서 정말 좋았다. 식사 후에는 피곤해서 9시 조금 넘어서 일찍 취침한 것 같다.
오늘은 새벽과 아침에 정말 공부를 많이 해서 가능하면 자바스크립트 심화 과정을 거의 끝내고 남은 수업도 모두 들어볼 생각이다. 그래서 저녁까지 해서 심화 과정을 웬만하면 다 끝내고 내일 새벽에는 그동안 정리하지 못했던 것들도 하는 시간을 갖기로 했다. 내일은 수료식이니 내 생애 정말 중요한 날이다.
이론 2 - 실행 컨텍스트
자바스크립트 엔진이 코드를 읽고 실행했을 때 전역 컨텍스트를 먼저 만들고 내부에서 함수가 호출된다.
코드에 실행 컨텍스트에 쌓이는 과정을 살펴보겠다. 먼저 실행 컨텍스트를 만들고 그 안에 Variable Object가 있다. console이 전역 object 안에 함수로 들어가 있다. console은 윈도우 밑에 있는 변수지만 편의상 전역에서 참조할 수 있는 변수로 넣어주었다.
f1을 호출했을 때 function Excution이 형성된다.
이제 f2 함수가 실행된다. fc에는 변수 c가 존재하고 a, b, c 변수가 차례대로 참조된다. 스코프 체인을 따라서 실행 컨텍스트를 찾아나가는 모습이다.
print 함수가 호출되는데 v 변수가 있다. console 객체는 로그 함수가 참조된다.
가장 마지막에 쌓였던 것이 가장 먼저 제거된다.
print 함수가 끝나고 f2 함수도 호출된다. f2 관련 컨텍스트가 제거된다.
f1 함수 호출이 끝나 f1까지 콜 스택에서 제거된다. 마지막으로 모든 컨텍스트가 끝나면 글로벌 컨텍스트도 빠지게 된다.
모든 함수 호출이 끝났을 때 자바스크립트는 전역 실행 컨텍스트로 돌아온다. 함수가 내부적으로 호출되다가 마지막에 전역 실행 컨텍스트가 존재한다. 콘솔 등의 전역 객체를 참조했을 때 스코프 체인을 따라 전역 실행 컨텍스트까지 참조한다. 가장 밑바닥에는 전역 컨텍스트가 있고 그 위에 함수 실행 컨텍스트가 쌓이게 된다.
이 과정을 정리해보면 자바 실행 코드가 없는 경우 전역 실행 컨텍스가 만들어지고 실행된다.
함수가 실행되면 함수 실행 컨텍스트가 만들어진다.
부록 1 - 실행 컨텍스트와 렉시컬 환경
퀴즈 2 - 실행 컨텍스트
이 문제는 너무 어려워서 무슨 말인지 파악하지도 못했다. 문제의 코드를 설명해 보면 다음과 같다. 이 코드는 JavaScript에서 객체와 메서드, 그리고 실행 컨텍스트에 대한 내용을 다루고 있다.
1. 객체 정의
const o = {
name: "Kim",
changeMyName: function (name) { this.name = name },
};
2. 다른 객체 정의
const o2 = {
name: "Song",
};
여기서 o2는 name을 “Song”으로 초기화한 또 다른 객체이다.
3. 콜백 함수
function callFuncWithArg(f, arg) {
f(arg);
}
이 함수는 첫 번째 인자로 함수 f를 받고 두 번째 인자로 arg를 받아서, f(arg)를 호출한다.
4. bird 메서드 사용
o.changeMyName.bind(o2)("Sam");
bind 메서드는 o.changeMyName의 this 값을 o2로 바꿔준다. 그래서 o2.name은 “Sam”으로 변경된다.
5. 로그 출력
console.log("1번 - ", o2.name);
여기서 o2.name은 “Sam”으로 출력된다.
6. callFuncWithArg 호출
callFuncWithArg(o.changeMyName, "Daniel");
여기서 o.changeMyName가 callFuncWithArg에 전달될 때, this는 o를 가리키지 않게 되어, 이 메서드는 전역 컨텍스트로 실행된다. 그래서 o.name은 여전히 “Kim”으로 유지된다.
7. 직접 메서드 호출
o.changeMyName("Sam");
이 코드는 o 객체의 메서드를 직접 호출하여 o.name을 “Sam”으로 변경한다. 결국 세 번의 console.log 출력이 있으며, 결과는 1번은 “Sam”, 2번은 “Kim”, 3번은 “Sam”이다.
2번 답안에서 보면 o의 changeMyName 메서드는 callFuncWithArg 함수에 전달될 때, 현재의 execution context가 유지되지 않고 글로벌 컨텍스트로 바뀌게 된다.
즉, callFuncWithArg(o.changeMyName, "Daniel"); 호출 시 changeMyName은 o2와 상관없이 글로벌 컨텍스트에서 실행되므로 o의 name은 변경되지 않고, 여전히 “Kim”으로 유지된다. 그러므로 2번의 결과는 “Kim”이 맞다.
드디어 답을 맞혔다.
실습 2 - Context 연산 함수 만들기
1. 문제 파일 실행하기
연산 결과가 나와야 하는데 지금은 나오지 않는다. 이제 함수를 만들어보기로 하자.
2. 코드 맞게 수정하기
mul에서는 n을 받아서 a, b를 곱한 결과를 반환하도록 한다. 이때 a, b는 실행 컨텍스트 외부에 있으므로 스코프 체인을 따라 variable object에 정의된 a, b 변수를 참조하게 된다. mul30에서는 num에도 a, b를 더한 값이 반환되도록 한다.
add30에서는 익명 함 수가 정의되어 있고 마지막에 add를 호출하는 형태의 코드이다.
각 변수가 어떤 스코프 내에 정의되어 있는지 아는 것이 중요하다.
3. 코드 실행하기
어떻게 해서 곱한 결과가 6000이 될까?
함수 mul에서는 a와 b의 값이 각각 10과 20으로 정의되어 있다. mul30 함수 안에서 n * a * b를 계산할 때, num에 30을 넣으면 다음과 같이 계산된다.
- a = 10
- b = 20
- num = 30
따라서 계산식은 다음과 같습니다.
30 * 10 * 20 = 30 * 200 = 6000
그래서 30을 곱한 결과는 6000이 나온다. 그리고 더한 값도 a = 10, b = 20을 더하고 여기에 입력값 30을 더하니 60이 되는 것이다.
학습을 마치고
퀴즈 문제와 실습 문제는 무척 어려웠지만 그래도 잘 해결했다. 아직 컨텍스트가 어떻게 해서 값이 출력이 되는 과정들을 잘 모르는 것 같다. 이 부분은 다음에 더 많은 훈련과 학습이 필요할 것 같다.
그래도 이런 구조로 인해 값이 변경되고 스택이 쌓이고 제거되는지 알게 되었다. 정말 많은 것을 얻은 수업이었다. 이어서 다음 학습도 진행해 보겠다.
'웹 · 앱 개발 > 자바스크립트' 카테고리의 다른 글
실행 컨텍스트 5 - 화살표 함수와 일반 함수의 this (1) | 2024.11.25 |
---|---|
실행 컨텍스트 4 - this가 가리키는 것 (1) | 2024.11.25 |
실행 컨텍스트 2 - 자바스크립트 함수가 실행되는 과정 (0) | 2024.11.24 |
실행 컨텍스트 1 - 자바스크립트 심화 수업 소개 (0) | 2024.11.24 |
도전! 크로켓 경기 소개 페이지 만들기 (제이쿼리 구현) 3 - 미션 문제 풀기 (0) | 2024.11.24 |