Skip to main content

JavaScript

기본 개념

Q. 자바스크립트는 무슨 언어인가요?
  • 자바스크립트는 웹 페이지에서 복잡한 기능을 구현할 수 있는 고수준의 인터프리터 기반 언어입니다. 프로토타입 기반의 객체지향 언어이며, 명령형·함수형·객체지향 프로그래밍이 모두 가능한 멀티 패러다임 언어입니다.
Q. 자바스크립트가 동적 언어인 이유는 무엇인가요?
  • 자바스크립트는 변수를 선언할 때 타입을 지정하지 않으며, 런타임에 값이 변경되면 그에 따라 타입도 함께 변하는 동적 타입 언어입니다. 또한 객체의 속성을 동적으로 추가·삭제할 수 있어 동적 언어라고 할 수 있습니다.
Q. 클로저란 무엇이고 적용할때 주의할점은 무엇인가요?
  • 클로저는 내부 함수가 자신이 선언된 렉시컬 환경을 기억하여, 외부 함수가 종료된 이후에도 그 환경에 접근할 수 있는 함수를 말합니다. 정보 은닉, 상태 유지, 콜백 구성 등 다양한 상황에서 유용하게 활용됩니다.

    다만 주의할 점이 있습니다. 클로저를 통해 외부 변수를 참조하는 내부 함수가 오랫동안 유지되면, 해당 변수가 메모리에서 해제되지 않아 메모리 누수가 발생할 수 있습니다. 특히 이벤트 리스너나 타이머 내부에서 사용할 때는 더 이상 필요하지 않다면 참조를 끊는 정리 작업이 필요합니다. 또한 클로저는 변수를 값이 아닌 참조로 기억하기 때문에, 여러 함수가 동일한 변수를 공유하면 의도치 않은 값 변경이 발생할 수 있어 주의가 필요합니다.

Q. 실행 컨텍스트에 대해 설명해주세요.
  • 실행 컨텍스트는 자바스크립트 코드가 실행되는 환경 정보를 담고 있는 객체입니다. 전역 코드가 실행될 때 전역 실행 컨텍스트가 생성되고, 함수가 호출될 때마다 각각의 실행 컨텍스트가 생성됩니다. 실행 컨텍스트는 스택 구조로 관리되며, 가장 위에 있는 컨텍스트가 현재 실행 중인 코드에 해당합니다.
Q. 클로저와 실행 컨텍스트를 연관지어서 설명해주세요.
  • 함수가 호출되면 새로운 실행 컨텍스트가 생성되고, 해당 컨텍스트에는 변수 객체, 스코프 체인, this 값 등이 포함됩니다. 함수 내부에서 선언된 하위 함수는 상위 함수의 실행이 종료된 이후에도 자신이 선언될 당시의 렉시컬 환경을 스코프 체인을 통해 참조할 수 있습니다.

    즉, 클로저는 실행 컨텍스트가 종료된 이후에도 그 안의 변수에 접근할 수 있도록 하는 메커니즘이라고 이해할 수 있습니다.

Q. 렉시컬 환경에 대해 설명해주세요.
  • 렉시컬 환경은 실행 컨텍스트의 구성 요소 중 하나로, 선언된 변수·함수·상위 스코프 정보 등을 담고 있는 객체입니다. Environment Record에는 실제 변수와 함수 식별자 및 값을 저장하고, Outer Environment Reference를 통해 외부 렉시컬 환경을 참조함으로써 스코프 체이닝이 이루어집니다.
Q. 스코프(Scope)에 대해 설명해주세요
  • 스코프는 변수나 함수가 유효한 범위, 즉 해당 변수나 함수에 접근할 수 있는 코드의 영역을 의미합니다.
Q. 스코프의 종류에 대해 설명해주세요.
  • 글로벌 스코프는 변수나 함수가 애플리케이션 전체에서 접근 가능한 경우입니다.

    함수 스코프는 함수 내에서 선언된 변수가 그 함수 내에서만 유효한 범위입니다.

    블록 스코프let이나 const로 선언된 변수가 블록 내에서만 유효한 범위입니다.

Q. 스코프 체인에 대해 설명해주세요
  • 스코프 체인은 자바스크립트에서 변수를 찾을 때, 각 스코프의 관계에 따라 변수를 차례로 검색하는 체인 구조입니다. 가장 안쪽 스코프부터 시작하여 변수를 찾을 때까지 바깥쪽으로 스코프를 넓혀나가며, 이를 통해 내부 함수가 외부 함수의 변수에 접근할 수 있게 됩니다.
Q. 호이스팅에 대해 설명해주세요.
  • 호이스팅은 자바스크립트 엔진이 코드를 실행하기 전에 변수 및 함수 선언을 해당 스코프의 가장 위쪽으로 끌어올리는 것처럼 동작하는 방식입니다. 실제로 코드가 물리적으로 이동하는 것은 아니며, 엔진이 코드를 파싱하는 과정에서 선언이 메모리에 먼저 등록됩니다.

    중요한 점은 선언만 끌어올려지고 값의 할당은 원래 자리에 그대로 남아있다는 것입니다.

Q. 자바스크립트의 메모리 관리에 대해 아는 대로 설명해주세요
  • 자바스크립트는 자동 메모리 관리를 사용합니다. 메모리 구조는 스택 두 가지로 나뉘는데, 스택에는 원시 타입을 저장하고 힙에는 객체 타입을 저장합니다. 모든 변수는 먼저 스택을 가리키며, 원시 값이 아닌 경우 스택에는 힙의 객체에 대한 참조가 저장됩니다.

    스택의 경우 함수가 종료되면 함수 내 변수들이 자동으로 정리되고, 힙의 경우 가비지 컬렉터가 더 이상 참조되지 않는 객체를 자동으로 제거합니다.

참고 : [번역] 자바스크립트의 메모리 관리 설명

Q. 콜 스택 (Call Stack)과 힙 (Heap)에 대해 설명해주세요
  • 콜 스택은 함수 실행 컨텍스트가 쌓이는 스택 구조입니다. 함수를 호출하면 스택에 추가되고, 실행이 끝나면 제거됩니다. 자바스크립트는 단일 스레드 환경이므로 콜 스택이 하나뿐입니다.

    은 동적 메모리 할당을 담당하는 영역으로, 콜 스택처럼 정해진 구조가 없으며 객체와 같은 참조형 데이터가 저장됩니다. 가비지 컬렉터에 의해 불필요한 객체가 정리되어 메모리가 관리됩니다.

Q. JS에서 Garbage Collection에 대해 설명해주세요.
  • 가비지 컬렉션은 자바스크립트가 사용하지 않는 메모리를 자동으로 정리해주는 기능입니다. 핵심 아이디어는 더 이상 도달 가능하지 않은 객체를 찾아 메모리에서 제거하는 것입니다. 여기서 도달 가능하다는 것은 코드 어딘가에서 참조를 통해 접근할 수 있다는 의미입니다.

    덕분에 개발자는 메모리 관리 부담을 크게 덜 수 있지만, 사용하지 않는 객체에 대한 참조를 코드 어딘가에 남겨두면 가비지 컬렉터가 해당 객체를 사용 중이라 판단해 메모리 누수가 발생할 수 있으므로 주의가 필요합니다.

Q. 엄격(strict) 모드에 대해 설명해주세요
  • 엄격 모드는 자바스크립트의 오류를 보다 엄격하게 검사하는 모드입니다. 선언하지 않은 변수에 값을 할당하면 에러를 발생시키고, 삭제할 수 없는 프로퍼티를 삭제하려 할 때도 에러를 냅니다. 또한 일반 함수 내에서 this가 전역 객체가 아닌 undefined를 가리키게 되어 의도치 않은 전역 오염을 막아줍니다.
Q. 일반 함수와 화살표 함수의 this 바인딩 차이에 대해서 설명해주세요.
  • 일반 함수는 호출 방식에 따라 this가 동적으로 결정됩니다. 객체의 메서드로 호출하면 해당 객체를, strict mode에서는 undefined를, non-strict mode의 최상단에서는 전역 객체를 가리킵니다.

    화살표 함수는 자체적인 this 바인딩을 갖지 않으며, 자신을 감싼 가장 가까운 상위 스코프의 this 값을 그대로 사용합니다.

Q. 일급 객체의 조건에 대해 설명해주세요
  • 일급 객체는 무명의 리터럴로 생성할 수 있고, 변수나 자료구조에 저장할 수 있으며, 함수의 매개변수에 전달하거나 반환값으로 사용할 수 있는 객체를 말합니다.
Q. Call By Value, Call By Reference에 대해 설명해주세요.
  • Call by Value는 함수를 호출할 때 인자로 값 자체의 복사본을 넘겨주는 방식입니다. 숫자, 문자열, 불리언 같은 원시 타입 데이터가 이 방식으로 전달되며, 함수 내부에서 값을 변경해도 외부 원본 변수에는 영향을 주지 않습니다.

    Call by Reference는 함수를 호출할 때 값이 저장된 메모리 주소를 넘겨주는 방식입니다. 자바스크립트에서 객체·배열 같은 객체 타입 데이터가 이 방식으로 동작하며, 함수 내부에서 객체 속성을 변경하면 외부 원본 객체에도 반영됩니다. 단, 함수 안에서 매개변수를 새로운 객체로 재할당하면 원본과의 연결이 끊어져 원본은 변경되지 않는다는 점에 주의해야 합니다.

Q. call, apply, bind에 대해서 설명해주세요.
  • call, apply, bind 모두 함수의 this 값을 명시적으로 설정하는 메서드입니다. call 은 인자들을 쉼표로 구분하여 개별적으로 전달하고 즉시 실행합니다.

    apply 는 인자들을 배열 형태로 전달하고 즉시 실행합니다.

    bindthis가 영구히 바인딩된 새로운 함수를 반환하며 즉시 실행하지 않습니다.

Q. this에 대해 설명해주세요
  • this는 자신이 속한 객체를 가리키는 식별자를 참조할 수 있는 키워드로, 호출되는 방식에 따라 값이 달라집니다. 전역에서는 window 또는 global을, 객체의 메서드에서는 해당 객체를, 클래스에서는 인스턴스를 가리킵니다. 화살표 함수에서는 상위 스코프의 this를 상속받습니다.
Q. 이터러블과 이터레이터 프로토콜에 대해 설명해주세요
  • 이터러블 프로토콜Symbol.iterator를 프로퍼티 키로 사용한 메서드를 직접 구현하거나 프로토타입 체인을 통해 상속받아, 호출 시 이터레이터를 반환하도록 하는 규약입니다. 이를 준수한 객체를 이터러블이라 합니다.

    이터레이터 프로토콜next 메서드를 소유하며, 호출 시 valuedone 프로퍼티를 갖는 이터레이터 리절트 객체를 반환하도록 하는 규약입니다. 이를 준수한 객체를 이터레이터라 합니다.

Q. 제너레이터에 대해 설명해주세요
  • 제너레이터는 실행을 중간에 멈췄다가 다시 시작할 수 있는 반복 가능한 함수입니다. function* 키워드로 정의하며, yield 키워드를 만나면 실행이 멈추고 next() 메서드를 호출하면 다시 이어서 실행됩니다. 제너레이터 객체는 이터레이터이자 이터러블이며, 필요한 값을 그때그때 생성하므로 메모리 효율성이 향상됩니다.

참고 : https://ko.javascript.info/generators

변수

Q. var, let, const 차이를 설명해주세요
  • var함수 스코프를 가지며, 선언 전에 접근해도 undefined를 반환합니다. 중복 선언과 재할당이 모두 가능합니다.

    letconst블록 스코프를 가지며, 선언 전에 접근하면 에러가 발생합니다. 중복 선언은 불가능하고, let은 재할당이 가능하지만 const는 재할당이 불가능합니다.

Q. TDZ에 대해 설명해주세요
  • TDZ(Temporal Dead Zone)let 또는 const로 선언된 변수가 초기화되기 전에 접근할 수 없는 영역을 의미합니다. letconst호이스팅이 되지만 초기화되지 않은 상태로 TDZ에 놓이기 때문에, 선언 코드 이전에 접근하면 ReferenceError가 발생합니다.
Q. JS의 데이터 타입에 대해 설명해주세요
  • 자바스크립트의 데이터 타입은 원시 타입객체 타입으로 나뉩니다. 원시 타입은 값이 변경되지 않는 불변 데이터로, number, boolean, string, undefined, null, bigInt, symbol이 있습니다. 객체 타입은 메모리 주소를 저장하기 때문에 변수에 값을 복사하면 주소만 복사되며, 원본이 변경되면 참조하고 있는 모든 변수에 영향을 줍니다.
Q. 변수 선언, 초기화, 할당의 차이점에 대해 설명해주세요
  • 선언은 자바스크립트 엔진에 변수의 존재를 알리며 메모리 공간을 확보하는 과정입니다. 초기화는 선언된 변수에 처음으로 값을 넣어주는 것으로, varlet은 값을 할당하지 않으면 undefined로 자동 초기화되지만 const는 반드시 선언과 동시에 초기화해야 합니다. 할당은 이미 선언된 변수에 새로운 값을 저장하는 것으로, const로 선언된 변수는 재할당이 불가능합니다.
Q. null / undefined / NaN 을 비교해서 설명해주세요.
  • undefined 는 변수가 선언은 되었지만 아직 어떤 값도 할당되지 않은 상태를 의미합니다.

    null 은 개발자가 의도적으로 값이 없음을 나타내기 위해 사용하는 값입니다.

    NaN 은 "Not a Number"의 약자로, 숫자 연산을 했지만 그 결과가 유효한 숫자가 아닐 때 나타나는 특별한 숫자 값입니다.

Q. 얕은 복사와 깊은 복사에 대해 설명해주세요
  • 얕은 복사는 객체나 배열의 1단계 속성만 복사하고, 중첩된 값은 참조를 복사합니다.

    깊은 복사는 객체나 배열의 모든 속성을 재귀적으로 복사하여, 중첩된 객체까지 완전히 새로운 값으로 복사합니다.

Q. 얕은 비교와 깊은 비교에 대해 설명해주세요
  • 얕은 비교는 두 객체나 배열의 참조만 비교하므로, 값이 같더라도 서로 다른 객체라면 false가 나올 수 있습니다.

    깊은 비교는 두 객체나 배열의 모든 속성과 원소를 재귀적으로 비교하여, 중첩된 내부 속성까지 동일한지 확인합니다.

Q. 자바스크립트에서 일어나는 데이터 형변환에 대해 설명해주세요.
  • 암묵적 변환+, == 등의 연산자를 통해 자바스크립트 엔진이 자동으로 타입을 변환하는 방식입니다.

    명시적 변환String(), Number() 등을 사용하여 개발자가 직접 데이터 타입을 변환하는 방식입니다.

프로토타입

Q. Prototype과 Prototype Chaining이란?
  • 자바스크립트의 모든 객체는 메서드와 속성들을 상속받기 위한 템플릿으로써 프로토타입을 갖습니다. 상속되는 속성과 메서드들은 각 객체가 아니라 객체 생성자의 prototype 속성에 정의되어 있습니다.

    프로토타입 체이닝은 객체에서 속성을 찾을 때 해당 객체에 없으면 부모의 프로토타입을 따라 체인을 타고 올라가며 탐색하는 구조입니다.

Q. 프로토타입과 일반 객체지향 언어의 차이는?
  • 프로토타입 기반 언어는 기존 객체를 복제하여 새 객체를 생성하지만, 일반 객체지향 언어는 클래스를 정의한 후 인스턴스를 생성합니다. 상속 방식에서도 프로토타입 체인을 통한 상속과 클래스 상속 구조로 차이가 있으며, this 바인딩도 프로토타입 기반에서는 호출 문맥에 따라 동적으로 결정되는 반면 일반 객체지향 언어에서는 고정적으로 인스턴스 자신을 가리킵니다.
Q. 프로토타입이 존재하는데, 왜 자바스크립트는 클래스를 도입했을까요?
  • prototype을 직접 다루는 방식이 어렵고 복잡했기 때문에, 문법의 직관성을 높이고 상속을 간결화하기 위해 클래스를 도입했습니다. 덕분에 코드 가독성과 유지보수성이 향상되었습니다. 다만 클래스를 도입했더라도 내부 동작 방식은 여전히 프로토타입을 사용하므로, 클래스는 문법적 설탕이라고 할 수 있습니다.
Q. 최상위 루트의 프로토타입은 무엇인가요?
  • 자바스크립트 프로토타입 체인의 가장 꼭대기, 즉 최상위 루트 프로토타입 객체는 Object.prototype 입니다. 거의 모든 자바스크립트 객체는 프로토타입 체인 어딘가에서 이 객체를 상속받으며, toString(), hasOwnProperty(), valueOf() 같은 공통 메서드들이 정의되어 있습니다. Object.prototype의 프로토타입을 확인하면 null 이 반환되는데, 이것이 프로토타입 체인의 종착점을 의미합니다.

이벤트

Q. 이벤트 버블링, 이벤트 캡쳐링, 이벤트 전파에 대해 설명해주세요.
  • 이벤트 전파는 HTML 요소에 이벤트가 발생했을 때 DOM 트리를 따라 이벤트가 전달되는 방식입니다. 이벤트 버블링은 이벤트가 발생한 타겟에서 시작해 부모 요소들을 거쳐 최상위 루트까지 전파되는 현상이고, 이벤트 캡쳐링은 반대로 최상위 루트에서 실제 타겟 요소까지 아래로 이벤트가 전달되는 현상입니다.

    이벤트 리스너에 별도의 옵션을 주지 않으면 버블링 단계에서 동작하며, 이 특성을 활용한 기법이 이벤트 위임입니다. 이벤트 위임은 여러 하위 요소에 각각 이벤트를 등록하는 대신, 공통 상위 요소에 이벤트를 등록하여 하위 요소들의 이벤트를 한 곳에서 처리하는 기법입니다.

Q. 이벤트 전파 제어
  • stopPropagation 은 이벤트의 전파를 차단하여 버블링이나 캡처링을 막을 수 있습니다. preventDefault 는 이벤트의 기본 동작을 취소하지만, 버블링이나 캡처링은 막을 수 없습니다.
Q. event.target과 event.currentTarget의 차이
  • event.target 은 이벤트가 실제로 발생한 DOM 요소를 가리키고, event.currentTarget 은 이벤트 리스너가 실제로 등록된 DOM 요소를 가리킵니다.

비동기 처리 방식

Q. 동기(sync)와 비동기(async)에 대해 설명해주세요
  • 동기 방식은 순차적으로 코드가 실행되는 방식으로, 이전 작업이 끝나야 다음 작업이 실행됩니다. 비동기 방식은 특정 작업이 끝날 때까지 기다리지 않고 다음 작업을 실행하는 방식입니다.
Q. 이벤트 루프에 대해 설명해주세요.
  • 이벤트 루프는 자바스크립트의 비동기 처리 메커니즘을 관리하는 핵심 구성 요소입니다. 자바스크립트는 싱글 스레드 기반으로 동작하지만, 이벤트 루프를 통해 비동기 작업을 효율적으로 처리합니다.

    콜 스택이 비어있으면 태스크 큐에 있는 작업을 스택으로 가져와 실행하는 것을 무한히 반복합니다. 태스크 큐에는 마이크로 태스크 큐매크로 태스크 큐가 있는데, 마이크로 태스크 큐는 Promise·async/await 등을 처리하고 매크로 태스크 큐는 setTimeout·setInterval 등을 처리합니다. 마이크로 태스크 큐의 우선순위가 더 높습니다.

    자바스크립트 자체는 싱글 스레드이지만 비동기 작업이 가능한 이유는, 브라우저나 Node.js와 같은 런타임 환경이 별도의 스레드에서 비동기 작업을 처리해주기 때문입니다.

Q. 자바스크립트에서 비동기 로직이 어떻게 동작하는지 설명해주세요.
  • 자바스크립트에서 비동기 동작이 가능한 이유는 이벤트 루프 때문입니다. 이벤트 루프는 콜 스택에 수행할 작업이 있는지 확인하고, 태스크 큐에 대기 중인 함수가 있는지 반복해서 확인합니다.

    비동기 작업은 메인 스레드가 아니라 브라우저나 Node.js의 별도 스레드에서 수행되며, 완료된 후 태스크 큐에 결과를 할당합니다. 즉, 자바스크립트 코드 실행은 싱글 스레드에서 이루어지지만 외부 Web API 등은 자바스크립트 외부에서 실행되기 때문에 비동기가 가능합니다.

Q. 더 자세한 이벤트 루프 동작
  • 이벤트 루프는 콜 스택을 먼저 확인한 후 마이크로 태스크 큐를 확인합니다. 마이크로 태스크 큐에도 데이터가 없다면 매크로 태스크 큐를 마지막으로 확인합니다. 렌더링은 마이크로 태스크 큐가 비워진 후에 일어나므로, 처리 순서는 콜 스택 → 마이크로 태스크 큐 → 렌더링 → 매크로 태스크 큐 순입니다.
Q. 콜백 함수에 대해 설명해주세요
  • 콜백 함수는 다른 함수의 인자로 넘겨지는 함수로, 어떤 함수가 실행된 후에 호출되는 함수를 말합니다.
Q. 콜백 지옥을 해결하는 방법을 설명해주세요
  • 여러 비동기 작업이 순차적으로 수행되어야 할 때 콜백 내부에 콜백을 중첩하다 보면 코드가 복잡해지고 디버깅이 어려워집니다. 이를 해결하기 위해 Promiseasync/await을 사용합니다.

참고 : https://developer-haru.tistory.com/57

Q. Promise/then 에 대해 설명해주세요.
  • Promise는 자바스크립트에서 비동기 작업을 처리할 수 있게 해주는 객체로, 대기 중인 pending, 성공한 fulfilled, 실패한 rejected 세 가지 상태를 가집니다. 비동기 작업이 성공하면 resolve를 반환하고, then을 통해 콜백 함수를 실행하는 방식으로 동작합니다. 콜백의 중첩 대신 then/catch 체인을 통해 가독성 높은 코드를 작성할 수 있습니다.
Q. async/await 에 대해 설명해주세요.
  • async/awaitPromise를 기반으로 한 문법으로, 비동기 작업을 동기 코드처럼 작성할 수 있게 해줍니다. .then 체인을 피할 수 있어 가독성이 높고, try/catch 문을 통해 비동기 함수 내부의 에러를 동기 코드처럼 처리할 수 있어 에러 핸들링도 명확해집니다.
Q. Promise.all()과 Promise.race()에 대해서 설명해주세요
  • Promise.all() 은 여러 개의 프로미스를 동시에 실행하고, 모든 프로미스가 성공적으로 완료될 때까지 기다린 후 결과 배열을 반환합니다. 배열의 순서는 각 프로미스가 시작된 순서를 따르며, 하나라도 실패하면 즉시 해당 에러를 반환하고 중단됩니다.

    Promise.race() 는 여러 개의 프로미스 중 가장 먼저 완료된 하나의 결과나 에러만을 반환하며, 나머지 프로미스들은 무시됩니다.

Babel, Webpack

Q. Babel과 같은 트랜스파일러(Transpiler)의 역할은 무엇인가요? 왜 현대 프론트엔드 개발에서 필요한가요?
  • 바벨의 핵심 역할은 최신 자바스크립트 문법으로 작성된 코드를 구형 브라우저에서도 동작할 수 있도록 이전 버전의 자바스크립트로 변환해주는 것입니다. 최신 기술을 사용하려는 개발자의 요구와 다양한 브라우저 환경을 지원해야 하는 현실 사이의 간극을 메워주는 필수적인 도구라고 할 수 있습니다.
Q. 웹팩(Webpack), Vite와 같은 모듈 번들러(Module Bundler)는 왜 필요하며, 주요 기능은 무엇인가요?
  • 모듈 번들러는 여러 개로 나뉘어진 코드 파일과 그 의존성을 분석해서, 브라우저가 효율적으로 로드할 수 있도록 하나 또는 몇 개의 최적화된 번들로 묶어주는 역할을 합니다. Babel을 통한 트랜스파일링, 코드 압축과 트리 쉐이킹을 통한 최적화, HMR을 통한 개발 생산성 향상 등의 기능을 제공하여 현대 프론트엔드 개발의 필수 도구로 자리잡고 있습니다.
Q. require vs import 를 비교해서 설명해주세요.
  • require동적 모듈로 실행되는 순간에 바로 불러오게 됩니다. import정적 모듈로 빌드 타임에 분석되며, 트리 쉐이킹이 가능해 최적화에 유리합니다.

함수

Q. 화살표 함수와 일반 함수의 차이
  • 화살표 함수와 일반 함수의 가장 핵심적인 차이는 this 처리 방식입니다. 일반 함수는 호출 시점에 this가 결정되는 반면, 화살표 함수는 자신을 감싸는 상위 스코프의 this 값을 그대로 물려받아 고정시킵니다.

    또한 화살표 함수는 더 간결한 문법을 제공하며, 인스턴스를 생성할 수 없어 prototype 프로퍼티도 없습니다. this, arguments, super, new.target 바인딩을 갖지 않아 이를 참조하면 상위 스코프의 값을 참조합니다.

Q. 함수 선언형과 함수 표현식의 차이
  • 함수 선언문과 함수 표현식은 호이스팅에서 차이가 납니다. 함수 선언문은 호이스팅이 발생하여 실제 코드 라인 이전에 호출해도 정상적인 값을 반환하는 반면, 함수 표현식은 실제 코드 라인 이전에 호출하면 에러가 발생합니다.
Q. 즉시 실행 함수(IIFE)에 대해 설명해주세요
  • 즉시 실행 함수는 함수를 정의하고 그 순간 즉시 실행되는 함수로, 단 한 번만 호출되고 다시 호출할 수 없습니다. 함수 내부에서 선언된 변수는 외부 스코프에 영향을 주지 않아 데이터 은닉이 가능하며, 한 번 실행되면 메모리에 남지 않아 일시적인 데이터 처리에 적합합니다.
Q. 커링(Currying)에 대해서 설명해주세요.
  • 커링은 여러 개의 인자를 받는 함수를, 하나의 인자만 받는 여러 개의 함수로 순차적으로 쪼개는 함수 변환 기법입니다. 예를 들어 add(a, b) 함수를 커링하면 curriedAdd(a)(b) 형태로 인자를 하나씩 전달할 수 있게 됩니다. 함수의 재사용성을 높일 수 있다는 장점이 있습니다.

자바스크립트 문법

Q. ES6에 대해서 설명해주세요.
  • ES6는 ECMAScript 2015의 다른 이름으로, 자바스크립트 언어의 아주 큰 변화이자 중요한 업데이트 버전입니다. letconst 도입, 화살표 함수, 모듈 시스템 등이 추가되어 자바스크립트를 강력하고 유지보수하기 쉬운 언어로 만들어 주었습니다.
Q. Rest 연산자와 Spread 연산자에 대해 설명해주세요
  • Rest 연산자는 여러 개의 인수를 받아 하나의 배열로 모아줍니다. Spread 연산자는 배열이나 객체의 요소를 펼칠 때 사용됩니다.
Q. 옵셔널 체이닝(Optional Chaining) ?. 과 Nullish Coalescing ?? 연산자는 무엇이며, 어떤 상황에서 유용하게 사용될 수 있나요?
  • 옵셔널 체이닝 ?. 은 객체의 속성이나 메서드에 접근할 때, 앞부분이 null이나 undefined이면 에러를 발생시키는 대신 즉시 평가를 멈추고 undefined를 반환합니다. 깊이 중첩된 객체에서 user?.profile?.address?.street처럼 안전하게 접근할 수 있어 유용합니다.

    Nullish 병합 연산자 ?? 는 왼쪽 피연산자가 null 또는 undefined 일 때만 오른쪽 피연산자를 반환합니다. 기존 || 연산자는 0, 빈 문자열, false 같은 falsy 값에도 오른쪽 값을 반환하는 문제가 있었는데, ??는 이를 해결하여 기본값 설정 시 더 정확하게 활용할 수 있습니다.

Q. JS의 Array.flat()을 어떻게 구현해볼 수 있을까요?
  • flat()은 중첩된 배열을 지정된 깊이까지 평탄화하여 새로운 배열을 반환합니다. 가장 직관적인 방법은 재귀를 이용하는 것입니다.

    새로운 빈 배열을 만들어 각 요소를 순회하면서, 요소가 배열이고 depth가 0보다 크면 재귀적으로 customFlat을 호출하여 결과를 펼쳐 추가하고, 그렇지 않으면 요소를 그대로 추가합니다. 모든 순회가 끝나면 결과 배열을 반환합니다.

Q. 불변성을 유지하려면 어떻게 해야하나요?
  • 불변성은 데이터가 생성된 후 그 상태를 변경하지 않는 것을 의미합니다. 변경이 필요하다면 원본을 수정하는 대신 변경 사항이 적용된 새로운 객체나 배열을 만드는 방식으로 접근합니다.

    원시 타입은 그 자체로 불변성을 갖고 있으므로 가능하면 원시 타입으로 값을 할당합니다. 가변적인 배열과 객체는 새로운 배열·객체를 생성하는 방식으로 접근하거나, Object.freeze()를 활용하여 객체를 불변하게 만들 수 있습니다.

성능 최적화

Q. requestAnimationFrame에 대해 설명해주세요
  • requestAnimationFrame 은 자바스크립트에서 애니메이션을 처리할 때 사용되며, 브라우저의 디스플레이 리프레시 주기에 맞게 동기화되어 호출됩니다. 매 프레임마다 한 번씩 실행되어 매끄럽고 부드러운 애니메이션을 제공합니다.

    또한 사용자가 다른 탭으로 전환하거나 페이지가 백그라운드에 있을 경우 애니메이션 실행을 중단하여 불필요한 CPU 리소스를 절약할 수 있습니다.

Q. 코드 스플리팅(Code Splitting)과 지연 로딩(Lazy Loading)은 무엇이며, 웹 성능 최적화에 어떻게 기여하나요?
  • 코드 스플리팅은 자바스크립트 번들을 여러 개의 작은 조각으로 나누는 것입니다. 현대 웹 애플리케이션은 번들 파일의 크기가 매우 커지는 경향이 있어, 이를 여러 파일로 분리해 처음에는 꼭 필요한 최소한의 코드만 로드하도록 만들어 초기 로딩 시간을 줄입니다.

    지연 로딩은 리소스를 당장 필요하지 않으면 로드하지 않고, 실제로 필요한 시점에 로드하는 기법입니다. 페이지 하단의 이미지나 특정 버튼을 클릭해야 보이는 컴포넌트 등 비핵심적인 리소스의 로딩을 뒤로 미루어 초기 로딩 속도를 크게 개선할 수 있습니다.

Q. 디바운스, 쓰로틀링에 대해서 설명해주세요.
  • 두 기법 모두 함수 실행 횟수를 조절하여 성능을 최적화하는 방법입니다.

    디바운스는 짧은 시간 내 연속되는 이벤트를 마지막에 하나로 처리하는 기법입니다. 이벤트가 연속으로 발생하는 경우 타이머를 리셋하며, 마지막 이벤트 후 일정 시간 동안 추가 이벤트가 없을 때 함수를 한 번만 실행합니다. 검색창 자동완성 API 요청 방지나, 창 크기 조절 완료 후 최종 계산 등의 상황에서 유용합니다.

    쓰로틀링은 일정 시간 간격으로 실행 횟수를 제한하는 기법입니다. 정해진 시간 간격 동안 최대 한 번만 함수를 실행하여, 이벤트가 100번 발생해도 핸들러는 단 한 번만 실행됩니다. 스크롤 애니메이션 처리나 API 호출 버튼 연타 방지 등의 상황에서 유용합니다.

기타

Q. AJAX에 대해 설명해주세요
  • AJAX는 JavaScript를 사용하여 비동기적으로 데이터를 요청하고 서버에서 받은 응답을 처리하는 방식입니다. 중요한 점은 페이지 전체를 새로고침하지 않고 필요한 데이터만 업데이트한다는 것으로, fetch API를 통해 사용할 수 있습니다.
Q. 왜 함수 실행을 Stack으로 관리하나요?
  • 가장 큰 이유는 함수의 호출 방식이 스택의 동작 방식인 후입선출(LIFO) 과 잘 맞기 때문입니다. 함수가 다른 함수를 호출하면 원래 함수는 잠시 멈추고 새로 호출된 함수가 실행되며, 새 함수가 끝나야 원래 함수로 돌아와 남은 작업을 이어가는 중첩 구조가 스택으로 자연스럽게 표현됩니다.