모던 자바스크립트 Deep Dive #3

Yejung·2022년 11월 1일
0

📚 22.11.01 3회차 스터디 정리본

📌 strict mode

  • strict mode가 뭔가요?

    • JS 언어 문법을 좀 더 엄격하게 적용해 오류를 발생시킬 가능성이 높거나 JS 엔진의 최적화 작업에 문제를 일으킬 수 있는 코드에 대해 명시적인 에러를 발생시키는 것
    • ES6에서 도입된 클래스와 모듈은 기본적으로 strict mode 적용
    • ES5부터 지원
    • ESLint는 strict mode가 제한하는 오류 + 코딩 컨벤션도 정의하고 강제할 수 있다.
  • strict mode 사용시의 또 다른 변화

    • 일반 함수의 this → undefined 바인딩 (원래는 전역)
    • 매개변수에 전달된 인수를 재할당하여 변경해도 arguments 객체에 반영 X
  • 사용할 때 주의할 점

    • 전역에 사용하는 것을 피하자
      • 외부 서드파티 라이브러리를 사용시 라이브러리가 non-strict인 경우도 있기 때문에 혼용되면 오류를 발생할 수 있다
      • 이러한 경우 즉시 실행 함수로 스크립트 전체를 감싸서 스코프를 구분하고 즉시 실행 함수 선두에 strict mode 적용
    • 함수 단위로 적용하는 것도 피하자
      • 함수마다 제각각 strict mode를 사용하거나 사용하지 않는 것은 바람직 하지 않고 모든 함수에 일일이 strict mode를 적용하는 것도 번거로운 일
      • strict mode가 적용된 함수가 참조할 외부 컨텍스트에 strict mode가 적용되어 있지 않다면 이 또한 문제 발생의 가능성
  • strict mode를 통해 무엇을 예방할 수 있죠?

    • 선언하지 않은 변수를 참조하는 것
    • delete 연산자로 변수, 함수, 매개변수를 삭제하는 것
    • 중복된 매개변수 이름을 사용하는 것
    • with문사용
    • 암묵적 전역 : 선언하지 않은 변수를 참조하면 ReferenceError
    • delete 연산자로 변수, 함수, 매개변수를 삭제하면 SyntaxError
    • 중복된 매개변수 이름 사용시 SyntaxError
    • with문 사용시 SyntaxError


📌 빌트인 객체

  • 빌트인 객체가 뭔가요? 종류는 어떤게 있죠?

    • 표준 빌트인 객체는 ECMAScript 사양에 정의된 객체
    • 애플리케이션 전역의 공통 기능을 제공
    • 개발자가 모든 기능을 구현하지 않고, 편하게 개발할 수 있도록 자바스크립트에서 기본적으로 제공하는 객체
    • JS 실행 환경 (브라우저 또는 Node.js)과 관계없이 언제나 사용 가능
    • 전역 객체의 프로퍼티로서 제공
    • 별도의 선언 없이 전역 변수처럼 언제나 참조 할 수 있음
    • Object, String, Number, Boolean, Math, Date, Symbol, RegExp, Map, Set, Promise, Error
    • 종류
      • 인스턴스를 생성할 수 있는 생성자 함수 객체
      • (생성자 함수 객체가 아닌) Math, Reflect, JSON
  • 래퍼 객체에 대해서 알고 있나요?

    • 문자열, 숫자, 불리언 값에 대해 마침표 표기법이나 대괄호 표기법처럼 객체처럼 접근하면 생성되는 임시 객체

    • 문자열, 숫자, 불리언, 심벌은 암묵적으로 생성되는 래퍼 객체에 의해 마치 객체처럼 사용될 수 있으므로 생성자 함수를 new 연산자와 함께 호출해 문자열, 숫자, 불리언 인스턴스를 생성할 필요 X

    • null과 undefined는 래퍼 객체 생성 X

      const str = "hello";
      
      // 원시 타입인 문자열이 래퍼 객체인 String 인스턴스로 변환
      console.log(str.length); // 5
      console.log(str.toUpperCase()); // HELLO
      
      // 래퍼 객체로 프로퍼티에 접근하거나 메서드를 호출한 후 다시 원시값으로 되돌린다
      console.log(typeof str); // string
    • 위와 같이 문자열에 대해 마침표 표기법으로 접근하면 그 순간 래퍼 객체인 String 생성자 함수의 인스턴스가 생성되고 문자열은 래퍼 객체의 [[StringData]] 내부 슬롯에 할당

    • 이때 문자열 래퍼 객체인 String 생성자 함수의 인스턴스는 String.prototype의 메서드를 상속받아 사용

    • 그 후 래퍼 객체의 처리가 종료되면 래퍼 객체의 [[StringData]] 내부 슬롯에 할당된 원시값으로 원래의 상태를 갖도록 되돌리고 래퍼 객체는 가비지 컬렉션의 대상

📌 this

  • this가 뭔가요?

    • 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수
    • this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.
    • 함수를 호출하면 arguments 객체와 this가 암묵적으로 함수 내부에 전달
    • 코드 어디서든 참조 가능
  • this 바인딩이란?

    • 바인딩 : 식별자와 값을 연결하는 과정
    • this와 this가 가리킬 객체를 바인딩하는 것
    • this 바인딩은 함수 호출 방식에 의해 동적으로 결정
  • this는 동적으로 바인딩이 된다고 하는데 바인딩되는 객체가 어떻게 다르나요?

    • java나 C++ 에서 this는 언제나 클래스가 생성하는 인스턴스를 가리킴

    • JS의 this는 함수가 호출되는 방식에 따라 this 바인딩이 동적으로 결정

      함수 호출 방식this 바인딩
      일반 함수 호출 (중첩함수, 콜백함수 포함)전역 객체
      strict mode가 적용된 일반 함수 내부의 thisundefined
      메서드 호출메서드를 호출한 객체
      생성자 함수 호출생성자 함수가 생성할 인스턴스
      apply / call / bind 메서드에 의한 간접 호출메서드에 의해 첫번째 인수로 전달한 객체
  • apply / call / bind

    • apply와 call

      • 함수를 호출하면서 첫 번째 인수로 전달한 특정 개체를 함수의 this에 바인딩
      • apply는 array로 묶어서 나머지 인수를 전달, call은 쉼표로 구분해서 나머지 인수 전달
      • 대표적인 용도 : arguments 객체와 같은 유사 배열 객체에 배열 메서드를 사용하는 경우
    • bind

      • 함수 호출 X, 첫번째 인수로 전달한 특정 개체를 함수의 this에 바인딩
      • 메서드의 this와 내부의 중첩 함수 또는 콜백 함수의 this가 불일치 하는 문제를 해결하기 위해 사용


📌 실행 컨텍스트

  • 실행 컨텍스트에 대해 말해보세요

    • 전역 코드 / 함수 코드 / eval 코드 / 모듈 코드 ⇒ 소스코드 평가 ⇒ 실행 컨텍스트 생성

    • 정의

      • 소스코드를 실행하는데 필요한 환경을 제공하고 코드의 실행 결과를 실제로 관리하는 영역
    • 코드 실행 준비

      1. 소스코드의 평가
        • 실행 컨텍스트 생성 + 변수, 함수 등의 선언문만 먼저 실행해 생성된 변수나 함수 식별자를 키로 실행 컨텍스트가 관리하는 스코프에 등록
      2. 소스코드의 실행 (= 런타임 시작)
        • 선언문을 제외한 소스코드가 순차적으로 실행
        • 소스코드 실행에 필요한 정보 (= 변수나 함수의 참조) 를 실행 컨텍스트가 관리하는 스코프에 검색해서 취득
        • 변수 값의 변경 등 실행 결과는 다시 실행 컨텍스트가 관리하는 스코프에 등록
    • 역할

      • 코드가 실행되려면 스코프, 식별자, 코드 실행 순서 등의 관리가 필요한데 이 모든 것들을 관리하는 역할
      • 식별자를 등록하고 관리하는 스코프와 코드 실행 순서관리를 구현한 내부 메커니즘으로 모든 코드는 실행 컨텍스트를 통해 실행되고 관리된다.
      • 식별자와 스코프 → 렉시컬 환경으로 관리
      • 코드 실행 순서 → 실행 컨텍스트 스택으로 관리
    • 실행 컨텍스트 스택

      • JS 엔진은 먼저 전역 코드를 평가해 전역 실행 컨텍스트 생성
      • 함수가 호출되면 함수 코드 평가해 함수 실행 컨텍스트 생성
      • 이때 생성된 실행 컨텍스트를 스택 자료구조로 관리하는데 이를 실행 컨텍스트 스택이라 부름
      • 코드의 실행 순서를 관리
    • Lexical Environment

      • 식별자와 식별자에 바인딩된 값, 상위 스코프에 대한 참조를 기록하는 자료구조
      • 실행 컨텍스트를 구성하는 컴포넌트 (식별자, 스코프 관리)
      • 실행 컨텍스트 = Lexical Environment 컴포넌트 + Variable Environment 컴포넌트
      • 책에서는 구분하지 않고 설명
      • 렉시컬 환경 = EnvironmentRecord + OuterLexicalEnvironmentRecord(상위 스코프)
    • 스코프 체인

      • 식별자를 검색할 때 실행중인 실행컨텍스트에서 식별자를 검색하기 시작 → 없으면 외부 렉시컬환경에 대한 참조가 가리키는 렉시컬 환경 (= 상위 스코프) 검색


📌 클로저

  • 클로저에 대해서 설명해주세요

    • 중첩함수에서 외부 함수보다 내부 함수가 더 오래 유지되는 경우 내부 함수는 이미 생명 주기가 종료한 외부 함수의 변수를 참조할 수 있는데 이러한 내부 함수를 클로저라고 한다.
    • 외부함수가 종료될 때 해당 실행컨텍스트는 실행컨텍스트 스택에서 제거되지만 외부함수의 렉시컬 환경은 inner 함수의 [[Environment]] 내부 슬롯에 의해 참조 → 가비지 컬렉션의 대상이 아니다
    • 클로저에 의해 참조되는 상위 스코프의 변수를 자유 변수라고 한다.
  • 클로저를 사용하면 뭐가 좋죠?

    • 의도치 않게 상태가 변경되지 않도록 상태를 안전하게 은닉하고 특정 함수에게만 상태 변경을 허용하기 위해 사용
  • 클로저를 어떻게 생성하나요?

    1. 내부(중첩) 함수가 익명 함수로 되어 외부 함수의 반환값으로 사용될 때
    2. 내부(중첩) 함수가 외부 함수의 스코프에서 실행될 때
    3. 내부 함수에서 사용되는 변수가 외부 함수의 변수 스코프에 포함되어 있을 때


📌 클래스

  • 자바스크립트에서 클래스가 생기기 전에는 어떤 방식으로 객체지향 패턴을 구현했나요?

    • 생성자 함수와 프로토타입을 통해 구현
  • 그럼 생성자 함수와 클래스는 어떤 차이가 있나요?

    1. 클래스를 new 연산자 없이 호출하면 에러 발생 / 생성자 함수를 new 연산자 없이 호출하면 일반 함수로서 호출
    2. 클래스는 상속을 지원하는 extends와 super 키워드 제공 / 생성자 함수는 해당 키워드 제공 X
    3. 클래스는 호이스팅이 발생하지 않는 것처럼 동작 / 함수 선언문으로 정의된 생성자 함수는 함수 호이스팅, 함수 표현식으로 정의한 생성자 함수는 변수 호이스팅 발생
    4. 클래스 내부는 암묵적으로 모두 strict mode 지정되어 실행 + 해제 불가 / 생성자 함수는 암묵적으로 strict mode 지정 X
    5. 클래스의 constructor, 프로토타입 메서드, 정적 메서드는 모두 프로퍼티 어트리뷰트 [[Enumerable]] 의 값이 false (= 열거되지 않는다)
  • 클래스 정의

    • 새로운 객체 생성 메커니즘

    • class 키워드를 사용해서 정의

    • 일급객체이고 함수로 평가

    • 클래스 몸체

      • constructor : 인스턴스 생성 및 초기화
      • 프로토타입 메서드 : 생성자 함수와 다르게 클래스 몸체에 정의한 메서드는 기본적으로 프로토타입 메서드가 된다
      • 정적 메서드 : 인스턴스를 생성하지 않아도 호출할 수 있는 메서드
    • 프로토타입 메서드와 정적 메서드 차이

      1. 각각 속해있는 프로토타입 체인이 다르다
      2. 정적 메서드는 클래스로 호출 / 프로토타입 메서드는 인스턴스로 호출
      3. 정적 메서드는 인스턴스 프로퍼티를 참조 X / 프로토타입 메서드는 인스턴스 프로퍼티를 참조 가능
  • 클래스의 상속

    • 상속에 의한 클래스 확장은 기존 클래스를 상속받아 새로운 클래스를 확장하여 정의

    • 상속에 의한 클래스 확장은 재사용 관점에서 매우 유용

    • extends 키워드 사용

    • super class - sub class

    • 프로토타입 메서드, 정적 메서드 모두 상속 가능

    • constructor를 생략하면 암묵적으로 정의

      // 암묵적으로 아래와 같다
      constructor(...args) { super(...args) };
    • super 키워드 : 수퍼클래스의 constructor를 호출

📌 스프레드 문법

  • spread 문법이 뭔가요?

    • ES6에서 도입된 문법으로 뭉쳐있는 여러 값들의 집합을 펼쳐서 개별적인 값의 목록으로 만드는 것.
    • 사용할 수 있는 대상은 Array, String, Map, Set, DOM 컬렉션, arguments와 같이 순회할 수 있는 이터러블에 한정
  • 어떤 상황에서 사용할 수 있죠?

    • concat과 splice를 대신
    • 배열 복사
    • 이터러블을 배열로 변환

📌 구조 분해 할당

  • 구조 분해 할당이 뭔가요?

    • 구조화 된 배열과 같은 이터러블 또는 객체를 구조 파괴해서 1개 이상의 변수에 할당하는 것
  • 구조 분해 할당은 크게 어떤 종류가 있나요?

    • 배열 구조 분해 할당
      • 할당 기준 : 배열의 인덱스
    • 객체 구조 분해 할당
      • 할당 기준 : 프로퍼티 키 (선언된 변수 이름과 프로퍼티 키가 일치하면 할당)

출처

문제 : https://github.com/junh0328/prepare_frontend_interview

모던 자바스크립트 deep dive
https://github.com/junh0328/prepare_frontend_interview

profile
이것저것... 차곡차곡...

0개의 댓글