console.log

[모던 자바스크립트 Deep Dive] 22 - 23 장 본문

개발공부/JavaScript

[모던 자바스크립트 Deep Dive] 22 - 23 장

foresight 2023. 8. 28. 00:27

22. this

this

  • 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수
  • 생성자 함수는 this로 자신이 생성할 인스턴스 가리킴
  • 자바스크립트 엔진에 의해 암묵적으로 생성됨
  • 코드 어디서든 참조 가능
  • this바인딩은 함수 호출 방식에 의해 동적으로 결정됨
    • 일반 함수 호출
      • 함수 내부의 this는 전역 객체 window를 가리킴
      • strict mode에서는 undefined 바인딩
      • 메서드 내에서 정의한 중첩 함수도 마찬가지
      • this를 명시적으로 바인딩하는 방법
        • this를 변수에 할당, 해당 변수 참조
        • 메서드 사용 : Function.prototype.apply , [Function.prototype.call](http://Function.prototype.call) , Function.prototype.bind
    • 메서드 호출
      • 함수 내부의 this는 메서드를 호출한 객체를 가리킴
      • 메서드 소유한 객체가 아닌, 메서드 호출한 객체 가리킴 !!!
    • 생성자 함수 호출 (new)
      • 함수 내부의 this는 생성자 함수가 생성할 인스턴스를 가리킴

<aside> 💡 Function.prototype.apply/call/bind 메서드에 의한 간접 호출

apply & call
- 함수를 호출하면서 `첫 번째 인수로 전달한 특정 객체`를 호출한 함수의 this에 바인딩
bind
- 앞선 두 메서드와 달리 함수를 호출하지 않음
- 다만 첫 번째 인수로 전달한 값으로 this 바인딩이 교체된 함수를 새롭게 생성해 반환함

</aside>

  • strict mode 적용 시 일반 함수 내부에서 this는 undefined

23. 실행 컨텍스트

소스코드의 타입

  • 전역 코드
    • 전역에 존재하는 소스코드
    • var 전역 변수, 전역 함수를 전역 객체으 프토퍼티와 메서드로 바인딩하고 참조하기 위해 전역 객체와 연결
    • 전역 코드가 평가되면 전역 실행 컨텍스트 생성
  • 함수 코드
    • 지역 스코프 생성 → 지역 변수, 매개변수, arguments 객체 관리
    • 생성한 지역 스코프를 전역 스코프 체인으로 연결
    • 함수 코드가 평가되면 함수 실행 컨텍스트 생성
  • eval 코드
    • strict mode 에서 독자적인 스코프 생성
    • eval 코드가 평가되면 eval 실행 컨텍스트 생성
  • 모듈 코드
    • 모듈별로 독립적인 모듈 스코프 생성
    • 모듈 코드가 평가되면 모듈 실행 컨텍스트 생성

소스코드의 평가와 실행

  • 소스코드 평가
    • 실행 컨텍스트 생성
    • 변수, 함수 등의 선언문 먼저 실행 (undefined초기화)
    • 생성된 변수나 함수 식별자를 키로 실행 컨텍스트가 관리하는 스코프에 등록
  • 소스코드 실행
    • 소스코드 실행에 필요한 정보 (변수, 함수의 참조)를 실행 컨텍스트가 관리하는 스코프에서 취득
    • 변수 값의 변경 등의 실행 결과는 다시 실행 컨텍스트가 관리하는 스코프에 등록

실행 컨텍스트의 역할

  • 전역 코드 평가
    • 전역 코드 실행 전 준비 단계
    • 선언문만 먼저 실행
    • 생성된 전역 변수와 전역 함수를 실행 컨텍스트가 관리하는 전역 스코프에 등록
  • 전역 코드 실행
    • 전역 코드 평가 후 런타임 시작
    • 전역 변수에 값이 할당되고 함수 호출됨
  • 함수 코드 평가
    • 전역 코드 실행 중 함수를 만나면 코드 실행 순서가 변경되어 함수 코드 평가 시작
    • 매개변수와 지역 변수 선언문 먼저 실행
    • 생성된 매개변수와 지역 변수를 실행 컨텍스트가 관리하는 스코프에 등록
    • this 바인딩 결정
  • 함수 코드 실행
    • 함수 코드 평가 후 런타임 시작
    • 매개변수와 지역 변수에 값이 할당되고 메서드 호출됨
  • 이처럼 코드가 실행되려면 스코프, 식별자, 코드 실행 순서 등의 관리 필요
    1. 선언에 의해 생성된 모든 식별자를 스코프를 구분하여 등록, 상태 변화 지속관리 가능해야 함
    2. 스코프는 중첩 관계에 의해 스코프 체인을 형성해야 함
    3. 현재 실행 중인 코드의 실행 순서를 변경할 수 있어야 하며 되돌아갈 수도 있어야 함

실행 컨텍스트 스택

const x = 1;
function foo() {
  const y = 2;

  function bar() {
    const z = 3;
    console.log(x + y + z);
  }
  bar();
}
foo(); // 6
  1. 전역 코드 평가하여 전역 실행 컨텍스트 생성 후 실행 컨텍스트 스택에 푸시
    1. 전역 변수 x와 전역 함수 foo 전역 실행 컨텍스트에 등록
    2. 이후 전역 코드 실행되기 시작하면 x에 값 할당, 전역 함수 foo 호출
  2. foo가 호출되면 foo 함수 코드 평가 후 foo함수 실행 컨텍스트 생성하여 실행 컨텍스트에 푸시
    1. foo 함수의 지역 변수 y, 중첩 함수 bar foo 함수 실행 컨텍스트에 등록
    2. 이후 함수 코드 실행되기 시작하면 변수 y에 값 할당, 중첩 함수 bar 호출
  3. bar가 호출되면 bar 함수 코드 평가 후 bar함수 실행 컨텍스트 생성하여 실행 컨텍스트에 푸시
    1. bar 함수의 지역 변수 z bar함수 실행 컨텍스트에 등록
    2. 이후 함수 코드 실행되기 시작하면 변수 z에 값 할당 후 console.log 메서드 호출
  4. bar함수 종료 후 bar함수 실행 컨텍스트를 실행 컨텍스트 스택에서 팝하여 제거
    1. foo 함수도 더 이상 실행할 코드가 없으므로 종료
    2. foo 함수 종료 후 foo함수 실행 컨텍스트를 실행 컨텍스트 스택에서 팝하여 제거
    3. 실행 컨텍스트에는 아무것도 남아있지 않게 됨
  • 실행 컨텍스트 스택의 최상위 실행 컨텍스트는 현재 실행 중인 코드의 실행 컨텍스트임 !!!

렉시컬 환경

  • 실행 컨텍스트를 구성하는 컴포넌트
    • 환경 레코드
      • 스코프에 포함된 식별자를 등록, 등록된 식별자에 바인딩된 값을 관리하는 저장소
    • 외부 렉시컬 환경에 대한 참조
      • 상위 스코프 가리킴
      • 해당 실행 컨텍스트를 생성한 소스코드를 포함하는 상위 코드의 렉시컬 환경
      • 이를 통해 단방향 링크드 리스트인 스코프 체인 구현
  • 식별자, 식별자에 바인딩 된 값, 상위 스코프에 대한 참조를 기록하는 자료구조
  • 실행 컨텍스트 스택 : 코드 실행 순서 관리 / 렉시컬 환경 : 스코프, 식별자 관리
  • 객체 형태의 스코프 생성 후 식별자를 키로 등록하여 식별자에 바인딩된 값을 관리

실행 컨텍스트의 생성과 식별자 검색 과정

  • 전역 객체 생성
    • 전역 코드 평가되기 이전에 생성
    • 빌트인 전역 프로퍼티, 빌트인 전역 함수, 표준 빌트인 객체 추가됨
    • Object.prototype 상속받음 —> 전역 객체도 프로토타입 체인의 일원
  • 전역 코드 평가
    • 전역 실행 컨텍스트 생성
      • 비어있는 전역 실행 컨텍스트를 생성하여 실행 컨텍스트 스택에 푸시
    • 전역 렉시컬 환경 생성
      • 전역 환경 레코드 생성
        • 전역 변수를 관리하는 전역 스코프, 전역 객체의 빌트인 전역 프로퍼티, 빌트인 전역 함수, 표준 빌트인 객체 제공
        • 객체 환경 레코드 생성
        • 선언적 환경 레코드 생성
      • this 바인딩
      • 외부 렉시컬 환경에 대한 참조 결정
  • 전역 코드 실행
    • 식별자 결정을 위해 식별자를 검색할 때는 실행 중인 실행 컨텍스트에서 식별자 검색하기 시작
  • foo 함수 코드 평가
    • 함수 실행컨텍스트 생성
    • 함수 렉시컬 환경 생성
      • 함수 환경 레코드 생성
      • this 바인딩
      • 외부 렉시컬 환경에 대한 참조 결정
  • foo 함수 코드 실행
  • bar 함수 코드 평가
    • console 식별자 검색
    • log 메서드 검색
    • 표현식 평가
    • console.log 메서드 호출
  • bar 함수 코드 실행 종료
  • foo 함수 코드 실행 종료
  • 전역 코드 실행 종료