prepare_frontend_interview 저장소에 있는 자바스크립트 내용을 구어체 느낌으로 정리한 글입니다.
저장소에는 자세한 개념적인 부분이 많이 있어서, 학습이 필요하다면 위 저장소를 참고하시면 좋습니다.
잘못된 부분이나, 보충이 필요한 부분이 있다면 댓글로 조언 부탁드립니다.
최근 업데이트: 23/02/09
객체지향 프로그래밍
객체지향 프로그래밍이란?
- 현실 세계의 사물처럼, 프로그래밍에 필요한 개념을 객체라는 개념으로 추상화하고, 객체들간의 상호작용을 중심으로 프로그래밍하는 패러다임을 의미합니다.
객체지향 프로그래밍에서 객체란?
- 좁은 의미로 객체는 클래스의 인스턴스라고 할 수 있고,
- 넓은 의미에서 객체는 속성과 행위로 이루어진 어떤 독립된 단위를 의미합니다.
객체지향 프로그래밍의 특징을 설명해주세요.
- 첫번째는 추상화입니다. 추상화는 객체간에 공통적인 특징이나 기능을 추출하는 것을 의미합니다.
- (예를 들어, 강아지와 고양이를 동물이라는 공통적인 특징으로 추상화 할 수 있습니다.)
- 두번째는 상속입니다. 상속은 기존 객체의 기능을 다른 객체에서 사용할 수 있도록 넘겨주는 것을 의미합니다.
- 세번째는 다형성입니다. 다형성은 어떤 메소드가 다양한 방식으로 동작할 수 있는 특징을 의미하는데, 오버라이딩이나 오버로딩을 통해서 구현할 수 있습니다.
- 마지막은 캡슐화입니다. 캡슐화는 필요한 데이터와 데이터를 사용하는 행위를 함께 묶어두고, 외부에서는 정해진 메소드를 통해서 객체와 상호작용 할 수 있는 특징을 의미합니다.
자바스크립트는 객체지향 프로그래밍 언어인가요?
- 자바스크립트는 여러가지 프로그래밍 패러다임을 따르는 멀티 패러다임 프로그래밍 언어이고, 그 중에서도 객체지향 프로그래밍도 가능한 언어입니다.
- 다만 자바나 C++과 같은 클래스 기반 객체지향 프로그래밍 언어라고는 할 수 없습니다.
프로토타입
프로토타입에 대해 설명해주세요.
- 자바스크립트는 객체들로 구성되어 있는데, 객체는 각각 프로토타입을 가지고 있습니다.
- 프로토타입을 통해 자바스크립트의 상속이 구현되어 있는데, 객체의 원형이라는 의미 그대로, 상위 객체의 속성이나 메소드를 하위 객체에서 사용할 수 있습니다.
- 객체에서 어떤 속성이나 메소드에 접근할 때, 현재 객체에 찾는 값이 없으면 해당 객체의 상위 프로토타입에서 접근할 값을 찾는것을 반복합니다. 이걸 프로토타입 체인이라고 합니다.
Strict Mode
Strict Mode에 대해 설명해주세요.
- strict mode 는 ES5에 추가된 문법으로, 더 엄격한 환경에서 자바스크립트 코드를 실행하도록 제한하는 문법입니다.
- strict mode는 “use strict” 라는 키워드를 작성해서 적용할 수 있습니다.
- strict mode가 적용되면 선언하지 않은 변수를 참조하거나, delete 를 통한 식별자 제거, with 문 사용 시 에러가 발생하고, 일반 함수 내부에서 this를 사용하면 this에 undefined가 바인딩됩니다.
클래스와 Strict Mode
- ES6에 추가된 class 문법을 사용하면, 클래스 내부의 body는 자동으로 Strict Mode로 실행됩니다.
Wrapper Object
래퍼 객체에 대해 설명해주세요.
- 자바스크립트에서 원시 타입을 제외한 나머지가 객체 타입입니다.
- 이런 원시 타입도 객체 타입처럼 사용해야 하는 경우가 있는데, 이때 자바스크립트 엔진이 원시 타입의 값을 일시적으로 연관된 객체로 변경하고 사용하게 됩니다. 이때 사용하는 객체를 래퍼 객체라고 부릅니다.
- 그리고 래퍼 객체는 사용이 끝나면 다시 원시 타입의 값으로 되돌아갑니다.
래퍼 객체 사용을 예를 들어주세요.
- 변수에 문자열을 할당하고, 변수에 .length 라는 프로퍼티를 참조하는 경우가 있습니다.
- 문자열 타입은 기본적으로 원시 타입이라서 객체처럼 프로퍼티를 가질 수 없습니다. 하지만 자바스크립트 엔진에서 String 이라는 래퍼 객체로 변경해주고, 객체의 프로퍼티에 접근하도록 처리하기 때문에 문제 없이 사용할 수 있습니다.
this
this에 대해서 설명해주세요.
- 자바스크립트에서 this는 일반적으로 자신이 속한 객체나 생성할 인스턴스를 가리키는 자기 참조 변수입니다.
this 바인딩이란?
- 바인딩은 식별자와 값을 연결하는 과정을 의미합니다.
- 자바스크립트에서 this는 호출되는 방식에 따라서 어떤 값이 연결될지 결정됩니다. 이걸 this 바인딩이라고 합니다.
상황에 따른 this 바인딩에 대해 소개해주세요.
일반적으로, 크게 4가지 방식으로 사용할 수 있습니다.
- 첫번째는 전역이나 일반 함수 내부에서 사용하는 경우인데, 이때 this는 전역 객체를 가리키게 됩니다.
- 두번째는 오브젝트 내부의 메소드에서 사용되는 경우인데, 이 경우 호출한 객체를 가리키게 됩니다.
- 세번째로 생성자 함수 내부에서 사용되는 경우인데, 이 경우에는 생성할 인스턴스를 가리키게 됩니다.
- 마지막으로 이벤트 리스너의 콜백 함수에서 사용하는 경우인데, 이 경우에는 이벤트의 current target과 같은 곳을 가리키게 됩니다.
몇가지 예외가 있는데,
- apply나 call, bind 라는 메소드를 통해 호출한 경우, 파라미터로 전달된 객체를 바인딩하게 됩니다.
- 그리고 ES6에 추가된 화살표 함수를 이용하는 경우입니다. 화살표 함수는 특정 this를 가지고 있지 않기 때문에, 바로 상위 환경에서 this를 참조합니다.
실행 컨텍스트
실행 컨텍스트에 대해 설명해주세요.
- 실행 컨텍스트는 해당 코드가 평가되고 실행되는 환경을 의미합니다.
- 조금 더 자세히 말하면, 코드를 실행하기 위해 필요한 정보를 모아놓은 컨텍스트들을 콜스택에 쌓아올리고, 스택에서 pop 하면서 실행하는 것을 의미합니다.
실행 컨텍스트 작동에 대해서 아는만큼 설명해주세요.
- 실행 컨텍스트는 크게 3가지 방식으로 생성됩니다. 프로그램이 실행될 때, 함수가 호출될 때, 마지막으로 eval 함수가 호출될 때 생성됩니다.
- 그리고 실행 컨텍스트가 생성되면 자바스크립트 엔진의 콜 스택에 쌓이게 되고, 가장 위에 쌓인 실행 컨텍스트부터 처리하면서 코드를 실행하고 스택에서 제거하게 됩니다.
- 실행 컨텍스트는 ES6 기준으로 렉시컬 환경(Lexical Environment) 변수 환경(Variable Environment)로 구성되어 있습니다.
렉시컬 환경
- 렉시컬 환경은 외부 참조 환경과 환경 레코드로 구성되어 있습니다. 외부 참조 환경은 자바스크립트의 스코프 체인과 연관된 개념으로, 상위 실행 컨텍스트의 렉시컬 환경에 연결되어 있습니다.
- 그리고 환경 레코드는 값들을 저장할 때 필요하고, 식별자 바인딩을 하는 선언적 환경 레코드와 with문 같은 특수한 상황에서 사용되는 객체 환경 레코드로 구성되어 있습니다.
변수 환경
- 변수 환경은 렉시컬 환경과 같이 외부 참조 환경과 환경 레코드로 구성되어 있습니다.
실행 컨텍스트에서 렉시컬 환경과 변수 환경이 나눠진 이유를 알고 있나요?
- 기존의 함수 레벨 스코프를 가지는 var 변수들은 변수 환경에 저장됩니다.
- 하지만 ES6 이후 실행 컨텍스트는 내부에서 일어나는 함수 선언, 블록문, try/catch 문과 같은 곳에서 새로운 렉시컬 환경이 생성됩니다.
- 그래서 새로운 블록 안에서 블록 레벨 스코프를 가지는 let, const 변수를 사용하면 렉시컬 환경이 여러개 생길 수 있기 때문에 분리했다고 생각합니다.
실행 컨텍스트 작동 방식에 대해서 설명해주세요.
- 실행 컨텍스트 작동 방식은 크게 생성 단계와 실행 단계로 구분할 수 있습니다.
- 생성 단계에서는 this가 바인딩되고, 스코프 체인을 위한 외부 환경 참조를 결정합니다. 그리고 이 과정에서 렉시컬 환경과 변수 환경의 환경 레코드에 식별자 정보를 수집합니다.
- 이때 환경 레코드에 변수와 같은 식별자들이 실행 단게 이전에 수집되기 때문에, 실제 선언문 이전에 변수에 접근하거나 함수를 호출할 수 있는 호이스팅이 발생합니다.
- 이후 실행 단계에서 자바스크립트 엔진이 실행 컨텍스트를 기반으로 실제 코드를 실행합니다.
클로저
클로저에 대해 설명해주세요.
- 클로저는 렉시컬 스코프 밖에서 실행되더라도, 렉시컬 환경을 기억하고 참조할 수 있는 함수입니다.
- 조금 더 자세히 설명하면, 함수 내부에서 사용하는 변수나 함수들은 함수가 선언된 시점의 스코프에서 결정되는데, 이걸 렉시컬 스코프라고 합니다.
- 일반적인 함수는 실행이 종료되면 더이상 참조할 수 없는데, 클로저는 렉시컬 환경을 기억하고 참조할 수 있습니다.
클로저의 장점을 설명해주세요.
- 클로저를 사용하면, 클로저가 어떤 함수 내부의 어떤 값들을 참조하고 있다면, 해당 함수의 생명주기가 종료되더라도 렉시컬 환경을 통해 참조할 수 있습니다.
- 이를 통해 은닉화와 캡슐화 효과를 얻을 수 있습니다. 함수 내부 변수를 접근하는 클로저를 생성하면, 그 함수는 클로저를 통해서가 아니면 더이상 내부에 접근할 수 없기 때문입니다.
클로저는 단점이 없나요?
- 일반적인 함수는 실행이 종료되면 가비지 컬렉션에 의해 메모리에서 해제됩니다.
- 하지만 클로저를 사용하면 사용이 종료된 함수 내부에 렉시컬 환경에 의해 참조가 가능하므로 메모리에서 해제할 수 없기 때문에 메모리를 사용하게 됩니다.
클로저를 예를 들어줄 수 있나요? (클로저를 사용해본 경험이 있나요?)
- 학부 수업에서 배운 커링 기법을 자바스크립트로 구현할 때 클로저를 사용했습니다.
- 그리고 자바스크립트 라이브러리로 리액트를 주로 사용하는데, 리액트의 setState와 같은 훅을 클로저를 통해 구현할 수 있습니다.
실제 코드를 작성해보세요.
function sum(x,y) {
return x+y;
}
function sum(a) {
return (b) => {
return a+b;
}
};
const add2 = sum(2);
const five = add2(3);
- sum 함수의 파라미터가 2개인 것을 커링 기법을 적용해서 파라미터를 분리했습니다.
- 클로저의 특성으로 sum이 반환하는 함수는 a 값을 기억하게 되고, add2 함수와 같이 사용할 수 있습니다.
const MyReact = (function(){
let _state;
function useState(initialValue) {
const state = _state || initialValue;
const setState = (newState) => {
_state = newState;
}
return [state, setState];
}
return { useState };
})();
- 리액트의 state 는 초기값을 지정한 이후에 다시 렌더링이 되서 함수가 호출되더라도 초기값으로 초기화되지 않습니다. 그리고 useState로 반환된 state를 직접 변경해도 실제 상태는 변하지 않습니다.
- 이걸 _state 값을 두고, useState 를 클로저로 선언해서 구현할 수 있습니다.
클래스
자바스크립트에서 객체지향 프로그래밍을 어떻게 구현하나요?
- ES5 의 생성자 함수를 이용하거나, 프로토타입 메서드를 사용해서 구현할 수 있습니다.
- ES6 에서 추가된 클래스 문법을 이용해도 마찬가지로 객체지향 프로그래밍을 구현할 수 있습니다.
클래스 문법의 특징이 있나요?
- 클래스로 선언하면 new 키워드 없이 호출할 수 없습니다.
- 그리고 extends, super 와 같이 클래스 기반 객체지향 언어에 친숙한 키워드가 추가되었고,
- 클래스 내부는 암묵적으로 strict mode가 적용됩니다.
- 또한 클래스는 let, const와 같이 블록레벨 스코프를 가지고, 호이스팅이 발생하지 않는 것 처럼 작동합니다.
- 마지막으로 클래스 내부에 선언된 프로퍼티들은 Enumerable이 false인 열거되지 않는 값으로 간주합니다.
클래스에는 어떤 값들이 포함되어 있나요?
- 클래스 내부에는 크게 생성자인 constructor와 프로토타입 메소드, 정적 메소드가 포함되어 있습니다.
- ES2022 이후로는 클래스 내부에 변수도 선언할 수 있습니다.
스프레드 문법
스프레드 문법에 대해 설명해주세요.
- ES6에 추가된 문법으로, 배열이나 문자열같이 나열할 수 있는 여러 값들을 하나 하나의 개별 값으로 분해하는 문법입니다.
- 값 앞에 점 세개를 붙여서 사용합니다.
스프레드 문법은 어디에 적용할 수 있나요?
- 스프레드 문법은 대상을 순회할 수 있는 iterable 에 적용할 수 있습니다.
- 예를 들어 배열, 문자열, Map, Set, DOM 컬렉션 등이 있습니다.
- 혹은 객체 리터럴 내부에서는 Object에도 적용할 수 있습니다.
구조 분해 할당
구조 분해 할당을 설명해주세요.
- 구조 분해 할당은 값을 해체해서 해체된 값을 개별 변수에 담을 수 있게 하는 문법입니다.
- 주로 배열이나 객체의 값들을 각 변수에 나눠서 할당할 때 사용합니다.
구조 분해 할당을 적용한 예시가 있을까요?
- 저는 주로 리액트 라이브러리의 컴포넌트를 선언할 때 사용합니다.
- 함수형 컴포넌트의 파라미터로 props를 넘겨주게 되는데, 이때 props 객체를 구조 분해 할당 문법을 사용하여 전달받습니다.
브라우저 렌더링 과정
브라우저 렌더링 과정에 대해 설명해주세요. (프론트엔드 위주)
다운로드
- 웹 브라우저에 사용자가 입력한 URL 주소를 DNS를 통해 IP 주소를 검색하고, 그 IP 주소에 HTTP GET 요청 메시지를 전송합니다.
- 네트워크를 통해 웹서버로부터 요청에 대한 웹 서버로부터 응답 메세지를 전달 받습니다.
파싱 (DOM 트리, CSSOM 트리 생성)
- 브라우저는 응답 메세지의 body에 있는 HTML를 문서를 파싱해 DOM 트리 생성을 시작합니다.
- 먼저 HTML 상단의 DOCTYPE 을 읽어서 HTML 버전을 체크하고, 그 이후 버전에 따라 HTML 파일을 마크업 단위로 시리얼라이징 합니다.
- 파싱 과정 중 link, script, img 와 같은 특수한 태그를 만나면 추가적인 일을 진행합니다.
- 예를 들어 스타일 파일을 가져오는 link 태그를 만날 경우, 파싱 과정을 잠시 멈추고 src에 있는 주소로 요청을 보내고, 응답이 오면 파싱 과정과 병렬적으로 파일을 파싱합니다. 즉, 이런 스타일 파일들을 파싱해서 CSSOM 트리를 생성합니다.
- 만약 script 태그를 만날 경우, 마찬가지로 파싱 과정을 잠시 멈추고 스크립트 해석과 실행이 끝날 때 까지 기다립니다.
Render 트리 생성
- 이런 파싱 과정이 끝나면, DOM 트리와 CSSOM 트리가 완성되고, DOM 과 CSSOM을 결합하여 렌더트리를 생성합니다.
레이아웃/페인트
- 마지막으로 레이아웃과 페인팅 과정을 통해 생성된 렌더 트리를 실제 브라우저에 표현합니다.
- 레이아웃 과정은 어떤 렌더 아이템이 어느 위치에 그려야 하는지 계산하는 과정입니다.
- 페인트 과정은 레이아웃 과정을 통해 얻은 위치에 실제로 요소를 그려내는 과정입니다.
리플로우/리페인트
- 브라우저는 위와 같은 방식으로 화면을 표시하고, 만약 DOM 이 조작되거나 하는 등의 이유로 화면을 다시 그려야 한다면 경우에 따라 다시 레이아웃 작업을 하는 리플로우와 다시 페인트 작업을 하는 리페인트 과정이 발생합니다.
브라우저 렌더링 과정에서 자바스크립트는 어떻게 작동하나요?
- HTML 파일 파싱 과정에서 script 태그를 만나면 파싱 과정을 멈추고, 만약 src 속성이 있다면 스크립트 파일을 받고, script 태그의 자바스크립트 파일을 해석하고 실행합니다.
- 만약 script 태그에 async 속성이 있으면, 파싱과 병렬적으로 스크립트를 다운로드하고, 다운로드가 종료된 직후 파싱 과정을 멈추고 스크립트를 처리합니다.
- 또는 script 태그에 defer 속성이 있으면, async 속성처럼 파싱과 병렬적으로 스크립트를 다운로드하지만, HTML 파일의 파싱이 종료된 이후에 스크립트를 처리합니다.
- 스크립트를 처리할 때, 자바스크립트 파일을 해석하고 실행하기 위해서 렌더링 엔진은 자바스크립트 엔진에게 제어권을 넘겨줍니다.
- 제어권을 받은 자바스크립트 엔진은 자바스크립트 코드를 해석해서 AST를 생성하고, AST를 기반으로 인터프리터가 실행할 수 있는 중간 코드를 생성해서 실행합니다.
- 모든 스크립트 처리가 끝나면 다시 자바스크립트 엔진에서 렌더링 엔진으로 제어권을 돌려주고, 남은 HTML 파일 파싱 과정을 진행합니다.
script 태그를 body 태그의 가장 아래 부분에 놓으면 좋은 이유가 있을까요?
- HTML 파일 파싱 중 script 태그를 만나면 HTML 파싱 과정을 멈추고 스크립트를 처리합니다. 그래서 HTML 파싱이 끝나지 않은 상태에서 스크립트를 처리하는 동안 남은 HTML 부분에 대한 지연 시간이 발생할 수 있습니다.
- 그래서 HTML 의 콘텐츠가 다 로딩된 body 태그의 마지막 부분에 script 태그를 위치시켜 로딩 지연을 줄일 수 있습니다.
- 하지만 기본적인 script 태그를 사용하면 body 태그의 마지막에 선언된 script 태그를 만난 이후에 다운로드를 시작하는 문제점이 있습니다. 이걸 해결하기 위해 script 태그에 defer 속성을 둬서 병렬적으로 다운로드 한 후, HTML 파싱이 끝난 후 스크립트를 처리할 수 있습니다.
DOM
DOM 에 대해 설명해주세요.
- DOM 은 HTML같은 문서의 구조와 정보를 나타내는 트리 형태의 인터페이스입니다.
- DOM 을 조작해서 HTML 요소의 속성이나 스타일, 이벤트 등을 수정할 수 있습니다. 이렇게 DOM 에 접근해서 변경하는 프로퍼티나 메소드를 DOM API라고 합니다.
DOM 구성 요소에 대해 알고 있나요?
- DOM 은 트리 형태의 자료구조이고, 크게 4가지 종류의 노드로 구성되어 있습니다.
- 첫번째는 Document Node로 트리 최상위에 위치하는 노드입니다.
- 두번째는 Element Node로 HTML Element 를 표현하는 노드입니다. 그리고 Element Node는 Attribute Node와 Text Node를 하위 노드로 가질 수 있습니다.
- 그래서 세번째와 네번째인 Attribute Node와 Text Node는 각각 해당 HTML Element 의 속성이나 텍스트를 나타내는 노드입니다.
이벤트
이벤트 핸들러를 등록하는 방식을 아는만큼 소개해주세요.
이벤트 핸들러 Attribute (onClick)
- HTML Element의 onClick과 같은 Attribute에 이벤트 핸들러 함수를 직접 등록할 수 있습니다.
<button onClick="()=>{...}"></button>
이벤트 핸들러 프로퍼티
- 자바스크립트에서 HTML Element를 참조하고, HTML Element의 이벤트 핸들러 프로퍼티를 직접 수정해서 이벤트 리스너를 등록할 수 있습니다.
const button = document.querySelector("button");
button.onclick = () => {...};
addEventListener 방식
- 자바스크립트에서 HTML Element를 참조하고, HTML Element에 addEventListener 메소드를 호출해서 이벤트 리스너를 등록할 수 있습니다.
이벤트 전파에 대해 알고 있나요?
- DOM 트리에 존재하는 Element에 대한 이벤트가 발생하면 DOM 트리를 통해 전파되는 특징이 있습니다.
- 이벤트 전파는 이벤트가 발생했을 때, 크게 캡처링 단계와 타겟 단계, 그리고 버블링 단계로 진행됩니다.
- 캡처링 단계는 상위 Element에서 하위 Element로 전파되는 과정으로, 처음 window 객체에서 시작해서 DOM 트리를 통해 이벤트가 등록된 이벤트 타겟까지 전파됩니다.
- 타겟 단계는 이벤트가 이벤트 타겟에 도달했을 때 과정으로, 이벤트 타겟에 등록된 이벤트 핸들러가 실행됩니다.
- 마지막으로 버블링 단계는 이벤트 타겟 Element에서 상위 Element로 전파되는 과정으로, 마찬가지로 window 객체까지 DOM 트리를 통해 전파됩니다.
event.target과 event.currentTarget 차이점을 설명해주세요.
- 실제로 이벤트가 발생한 가장 안쪽의 Element 를 타겟이라고 부르고, 이벤트 핸들러의 event.target으로 접근할 수 있습니다.
- 그리고 이벤트 핸들러가 직접 등록된 Element 는 이벤트 핸들러에서 event.currentTarget 또는 this로 접근할 수 있습니다.
- 차이점으로는 전파 단계에 따라 event.target은 변할 수 있지만, 이벤트가 처리될 때 핸들러가 등록된 event.currentTarget 은 변하지 않는다는 점이 있습니다.
이벤트 버블링과 캡쳐링을 적용하는 방법을 설명해주세요.
- 기본적으로 이벤트는 버블링이 적용되어 있습니다.
- DOM Element의 addEventListener 메소드의 세번째 파라미터인 useCapture 파라미터를 사용하면 전파 방법을 변경할 수 있습니다.
- 기본값은 false로 이 경우 버블링이 적용되고, true를 전달 할 경우 캡처링이 적용됩니다.
이벤트 전파를 막는 방법이 있나요?
- 이벤트 전파를 막기 위해 이벤트 리스너의 이벤트 객체의 몇가지 메소드를 사용할 수 있습니다.
- 먼저 Element 에 있는 기본 이벤트를 제거하기 위해 e.preventDefault() 메소드를 사용할 수 있습니다.
- 그리고 e.stopPropagation() 메소드를 사용하면 이벤트 전파가 이후의 Element로 전달되지 않도록 제한할 수 있습니다.
- 만약 동일한 Element에 여러개의 이벤트 리스너가 있을 때, e.stopImmediatePropagation() 메소드를 사용하면 다른 이벤트 리스너 호출을 제한합니다.
이벤트 위임에 대해 알고 있나요?
- 이벤트 위임은 연속되는 Element들 각각에 이벤트 리스너를 등록하는 대신, 상위 Element에만 이벤트 리스너를 등록하는 방식입니다.
- 이벤트 위임을 사용하면 등록할 이벤트 리스너를 줄일 수 있어서 메모리를 아낄 수 있고, Element 추가나 삭제마다 이벤트 리스너를 관리할 필요가 없어지는 장점이 있습니다.
이벤트 위임을 사용한 적이 있나요?
이벤트를 처리할 때 debounce나 throttle에 대해 알고 있나요?
- 마우스 scroll 이나 resize와 같은 이벤트는 보통 연속적으로 일어나기 때문에 짧은 시간동안 이벤트 리스너가 과도하게 호출될 수 있습니다. 과도한 함수 호출이 발생하면 성능이 떨어질 수 있기 때문에, 이런 성능 저하를 막기 위한 방법인 debounce와 throttle이 있습니다.
- debounce는 이벤트가 실행했을 때 일정 시간만큼 지연한 후 이벤트를 수행하도록 하고, 지연할 동안 같은 이벤트가 발생하면 이전 요청을 취소합니다.
- throttle은 일정 시간동안 일어난 이벤트들을 1번만 실행하도록 합니다.
타이머
타이머 함수에 대해 알고 있나요?
- 일정 시간 후나 일정 시간마다 작업을 처리하는 함수를 타이머 함수라고 합니다.
- 타이머 함수의 종류로는 대표적으로 setTimeout과 setInterval 이 있습니다.
- 그리고 기본적으로 시간을 ms단위를 사용합니다.
setTimeout에 대해 설명해주세요.
- setTimeout은 일정 시간 이후에 콜백 함수로 등록된 함수를 호출하는 함수로, 타이머가 만료될 때 딱 한번 실행됩니다.
- setTimeout 함수의 반환값으로 타이머를 식별하는 고유한 값을 반환하는데, 이를 clearTimeout 함수에 전달하면 타이머를 취소할 수 있습니다.
setInterval에 대해 설명해주세요.
- setInterval은 일정 시간마다 콜백 함수로 등록된 함수를 호출하는 함수입니다.
- setInterval도 마찬가지로 함수의 반환값으로 고유한 값을 반환하는데, clearInterval 함수를 통해 반복 호출을 취소할 수 있습니다.
동기/비동기
동기와 비동기의 차이를 알고 계신가요?
- 동기와 비동기는 작업을 처리하는 순서와 관련이 있습니다.
- 동기적으로 처리할 경우 현재 작업이 끝난 후 다음 작업이 시작하는 순차적인 작업 순서를 가지고 있지만,
- 비동기적으로 처리할 경우 작업이 끝나지 않았더라도 다음 작업을 시작할 수 있는 작업 순서를 가질 수 있습니다.
비동기 호출은 어떤식으로 진행되나요?
- 기본적으로 자바스크립트는 싱글 스레드로 동작해서 한번에 하나의 작업만 처리할 수 있습니다.
- 즉 콜스택에 쌓인 실행 컨텍스트를 위에서 아래로 하나씩 처리하고, 작업이 끝나면 스택에서 pop 하는 방식으로 동작합니다.
- 이때 자바스크립트는 브라우저에서 동작합니다. 자바스크립트가 동작할 때 브라우저는 자바스크립트를 처리하기 위해 자바스크립트 런타임이라고 하는 환경을 제공합니다. 싱글 스레드인 자바스크립트 엔진을 포함해서 Web API, 이벤트루프, 태스크 큐가 여기에 해당됩니다.
- 그래서 비동기 호출은 이 자바스크립트 런타임에 의해 처리할 수 있습니다.
- 콜 스택에서 비동기 호출이 발생하면 Web API 에서 처리하게 됩니다. Web API는 비동기 호출을 처리하고, 비동기 호출에 대한 콜백함수 등을 태스크 큐에 등록합니다.
- 이벤트루프는 콜스택과 태스크 큐를 확인하면서 콜 스택이 모두 처리되었을 때 태스크 큐에서 콜백 함수를 콜 스택으로 가져와서 처리하게 됩니다.
- 그래서 아래 코드는 ABC가 아닌 ACB 순서로 출력하게 됩니다.
console.log("A");
setTimeout(() => console.log("B"), 0);
console.log("C");
마이크로 태스크 큐에 대해 알고 있나요?
- 마이크로 태스크 큐는 또다른 종류의 태스크 큐로, 이벤트 루프가 콜 스택으로 태스크를 처리할 때 일반 태스크 큐보다 높은 우선순위로 처리하는 태스크 큐입니다.
- Promise 의 then이나 catch, finally 에 있는 콜백 함수거나, await 문법이 사용되었을 때 마이크로 태스크 큐에 등록됩니다.
통신 (Ajax, JSON, REST)
Ajax에 대해 설명해주세요.
- Ajax는 자바스크립트의 비동기 통신을 이용해 클라이언트와 서버간에 XML 데이터를 주고받는 기술을 의미합니다.
- Ajax는 브라우저 호스트 API인 XMLHttpRequest 객체를 기반으로 동작합니다.
Ajax를 활용한 방식의 장점이 있을까요?
- Ajax를 통해 특정 부분만 렌더링하는 방식의 개발이 가능해졌습니다. 왜냐하면 변경이 필요한 부분의 데이터만 Ajax 통신을 통해 요청하고, 응답한 데이터를 통해 특정 부분만 다시 렌더링할 수 있기 때문입니다.
- 변경이 필요한 부분만 다시 렌더링하기 때문에 새로고침이나 새로운 문서를 받았을 때 처럼 화면 깜빡임이 발생하지 않고, 비동기 통신이기 때문에 블로킹이 따로 발생하지 않습니다.
Ajax 통신을 위한 방법을 설명해주세요.
- 전통적인 방법으로 XMLHttpRequest 객체를 생성하고 설정해서 사용하는 방법이 있습니다.
- 최근에는 fetch API를 주로 사용하고 있습니다. fetch API는 비교적 최근에 추가된 Web API로 HTTP 요청 기능을 제공하는 함수입니다.
XMLHttpRequest와 fetch의 차이점이 있나요?
- 공통적으로는 둘 다 Ajax 통신을 위해 사용됩니다.
- 하지만 fetch의 장점은 Promise를 기반으로 구성되어 있어서 더 간편하게 사용할 수 있다고 생각합니다.
JSON에 대해 설명해주세요.
- JSON은 JavaScript Object Notation의 약자로, HTTP 통신을 위한 일종의 데이터 포맷입니다.
- 이름에 자바스크립트가 들어가지만, 자바스크립트에 종속되지 않은 언어 독립형 데이터 포맷입니다.
- JSON의 형태는 자바스크립트의 객체와 비슷하게 key-value 형태로 구성되어 있습니다. 하지만 key를 포함한 문자열을 항상 쌍따옴표로 표시해야 하고, 함수나 undefined와 같은 몇가지 자바스크립트의 타입을 사용할 수 없는 차이점이 있습니다.
자바스크립트에서 JSON 처리를 위한 메소드를 알고 있나요?
- 자바스크립트는 JSON 처리를 위해 표준 빌트인 객체로 JSON 객체를 가지고 있습니다. 그리고 JSON 객체의 메소드로 parse와 stringify 메소드가 있습니다.
- JSON.parse 메소드는 JSON 텍스트를 분석해서 자바스크립트 값이나 객체를 생성하는 메소드입니다.
- JSON.stringify 메소드는 자바스크립트 객체를 JSON 문자열로 변경하는 메소드입니다.
- 여기서 자바스크립트에서 서버 전송을 위해 객체를 문자열로 변경하는 것을 직렬화, 그리고 문자열을 다시 객체로 변경하는 것을 역직렬화라고 합니다.
REST API에 대해 알고 있나요?
- REST는 어떤 리소스를 이름으로 구분해서 자원의 상태를 주고받는 방식을 의미합니다.
- 조금 더 자세히 설명하면 HTTP URI를 통해 리소스을 명시하고, HTTP 요청 메소드를 통해 해당 리소스의 상태를 주고받는 방식을 의미합니다.
- REST API는 이런 REST를 기반으로 작성된 API 서비스를 의미하고, REST 원칙을 잘 지킨 디자인을 RESTful이라고 표현합니다.
REST API의 구성요소에 대해 알고 있나요?
- 크게 리소스와 행위, 그리고 표현으로 구성되어 있습니다.
- 리소스는 해당 리소스 그 자체를 가지고 있고, URI를 통해 표현합니다.
- 행위는 리소스에 대해 어떤 행위를 할 지를 의미하고, HTTP 메소드를 통해 전달합니다.
- 마지막으로 표현은 리소스에 대한 구체적인 행위의 내용이고, 페이로드를 통해 전달합니다.
REST API에서 HTTP 요청 메소드에 대해 아는만큼 설명해주세요.
- GET 메소드는 리소스를 가져오기 위해 사용합니다.
- POST 메소드는 새로운 리소스를 생성하기 위해 사용합니다.
- PUT과 PATCH 메소드는 기존 리소스를 수정하기 위해 사용합니다. 이때 PUT은 리소스 전체를 변경하고, PATCH는 일부만 수정한다는 차이가 있습니다.
- 마지막으로 DELETE는 리소스를 삭제하기 위해 사용합니다.
Promise
콜백 함수를 설명해주세요.
- 콜백 함수는 다른 함수의 파라미터로 전달되는 실행 가능한 코드로, 어떤 작업이 끝나거나 이벤트가 발생했을 때 호출되는 함수를 의미합니다.
- 일반적으로 비동기 함수 처리가 끝나면 실행할 작업으로 콜백 함수를 전달합니다.
Promise 문법에 대해 설명해주세요.
- Promise는 비동기 처리를 위해 ES6에서 추가된 문법입니다.
- Promise 객체는 new 키워드를 통해 생성할 수 있고, resolve와 reject를 파라미터로 하는 함수를 전달받습니다. resolve는 비동기 처리가 성공했을 때 호출할 함수고 reject는 비동기 처리가 실패했을 때 호출할 함수입니다.
- Promise는 세가지 상태를 가지는데, 비동기 처리중인 pending, 수행이 성공적으로 끝난 fulfilled, 오류가 발생한 reject 상태를 가지고 있습니다. 그리고 pending이 아닌 두 상태는 setteled 상태로, 더이상 변경되지 않는 상태입니다.
- fulfilled 상태의 Promise는 .then 을 통해 처리 값을 전달받아서 추가적인 처리가 가능합니다.
- 그리고 reject 상태의 Promise는 .catch를 통해 실패에 대한 처리가 가능합니다.
Promise 표준 빌트인 객체가 제공하는 메소드를 알고 있나요?
- Promise.all 메소드는 여러개의 비동기 처리를 병렬적으로 처리할 때 사용합니다. 각각의 비동기 호출이 순서가 상관 없을 때 사용합니다.
- Promise.race 메소드는 여러개의 비동기 처리 중 가장 먼저 fulfilled 된 처리 결과를 가져올 때 사용합니다.
- 마지막으로 Promise.allSettled 메소드는 여러개의 비동기 처리가 모두 fulfilled나 reject 된 처리 결과를 resolve하는 Promise를 반환합니다.
async/await
async/await 문법에 대해 알고 잇나요?
- ES8에 추가된 async/await는 Promise를 기반으로 동작하는 비동기 처리 방식입니다.
- async/await를 사용하면 비동기 처리를 동기 처리처럼 보이는 코드를 작성할 수 있습니다. 왜냐하면 Promise에 await 키워드가 사용된 경우 항상 프로미스가 settled(완료된) 상태가 될 때 까지 기다리기 때문입니다.
Promise와 차이가 있나요?
- async/await를 사용하면 에러 핸들링이 더 간단했습니다. Promise도 catch를 통해 에러 핸들링이 가능하지만, try/catch를 사용할 수 있는 async/await가 더 간단하다고 느꼈습니다.
- 그리고 Promise도 후속 처리가 많아질수록 then 내부에 코드가 중첩되면서 코드 흐름이 복잡해지는데, 이를 해결할 수 있습니다.
Generator
제너레이터에 대해 알고 있나요?
- ES6에서 추가된 문법으로, 코드 블록의 실행을 중지했다가 필요한 시점에 다시 실행할 수 있는 특수한 객체입니다.
- 제너레이터를 사용하면 제너레이터 함수의 제어권을 양도할 수 있고, 제너레이터 함수의 상태를 주고받을 수 있습니다.
제너레이터에 대해 조금 더 자세히 설명해주세요.
- 제너레이터 함수는 function 뒤에 *(star)를 붙인 키워드로 선언합니다.
- 제너레이터 함수 내부에는 yield 키워드를 사용할 수 있습니다.
- 제너레이터 함수를 호출하면 제너레이터 객체를 반환하는데, 바로 함수가 실행되지는 않습니다.
- 제너레이터 객체의 next 메소드는 현재 상태에서 가장 가까운 yield 키워드가 있는 곳 까지 실행됩니다. 그리고 메소드의 반환값으로 yield 키워드 뒤에 있는 값이 value로 반환됩니다. 이때 value와 함께 제너레이터의 마지막을 나타내는 불린값인 done도 함께 객체로 반환됩니다.
제너레이터의 특징을 알고 있나요?
- 제너레이터는 iterable로 취급됩니다. 그래서 제너레이터 객체를 for-of 문법 등으로 순회할 수 있습니다.
- 주의점으로는 제너레이터에서 done: true 가 되는 지점은 순회하지 않는다는 특징이 있습니다.
이정도면 합격은 문제없겠는걸요