프론트엔드 기술면접_JS(2)

최유나·2025년 7월 21일
1

JS

1. 변수를 선언할 때 쓰는 var, let, const의 차이에 대해 알려주세요.

자바스크립트 기본 지식, 스코프에 대한 이해도, 추가로 호이스팅에 대한 지식을 가지고 있는지 확인하는 질문.

각각 순서대로 설명드리겠습니다.
var의 경우에는 함수 스코프를 가지며, 초기화 전에 접근하면 호이스팅 덕분에 undefined를 반환합니다.
es6에서 추가된 constlet의 경우에는 블록 스코프를 가지며 호이스팅은 일어나지만 초기화 전에 접근 시 오류가 발생합니다.
이 중 constlet은 초기화 이후 재할당이 가능하냐의 의미에서 다시 갈라집니다. const는 상수라는 뜻의 constant의 약자로 초기화 이후 재할당이 불가능합니다. 따라서 코드의 예측 가능성을 높여주는 장점이 있다고 할 수 있습니다.
현재에는 블록 스코프를 가졌다는 점과 유지 보수가 용이하다는 점 때문에 const/let만을 사용하는 편입니다.

  • var: 예전 방식. 함수 안에서만 유효함. 블록 {}을 무시하고 밖에서도 보임. 선언 전에 써도 undefined로 나옴. (호이스팅 됨)
  • let: 요즘 방식. 블록 안에서만 유효함. 선언 전에 쓰면 에러.
  • const: let이랑 비슷하지만, 한 번 값 주면 못 바꿈.

💡 지금은 var 거의 안 쓰고, let이나 const만 씀. 바꿀 일이 없으면 const, 바뀔 수 있으면 let.

2. 쓰로틀링과 디바운싱의 개념과 사용하는 이유 및 대표적인 사용처에 대해서 설명해주세요.

성능 최적화 및 각 개념을 어디에 적용하면 좋을지 확인하는 질문.
마지막에 정리하는 말을 넣어주셔도 좋습니다. 사용한 경험에 대해서도 언급하면 좋습니다.

두 개념 모두 특정 함수의 실행 빈도를 조절하는 기술이지만 서로의 차이점 때문에 사용처가 다릅니다.
먼저 쓰로틀링의 경우에는 일정 간격마다 함수를 실행하도록 횟수를 제한하는 기술입니다. 예를 들어 스크롤 이벤트처럼 순식간에 여러 번 실행되는 이벤트는 성능 저하를 일으키기 쉬운데요. 여기에 쓰로틀링을 적용해주면 스크롤할 때마다가 아닌 설정한 간격마다 함수를 실행하기에 불필요한 호출을 줄여 성능을 향상시킬 수 있습니다.
그리고 디바운싱은 연속된 함수의 호출이 들어올 경우 무시하고 있다가 제일 마지막에 호출된 함수만을 실행하도록 하는 기술입니다. 대표적인 사용처는 검색어 자동 완성입니다. 유저의 인풋 중간 결과는 중요하지 않기에 전부 스킵해버리고, 마지막 결과 값에 대해서만 자동 완성 결과를 보여주면 불필요한 검색 요청을 줄여 성능을 향상시킬 수 있습니다.
다시 말해 지속된 이벤트의 호출에서 중간 호출도 중요하면 쓰로틀링을, 마지막 호출만이 중요하면 디바운싱을 사용하는 것이 좋습니다.

둘 다: 함수를 너무 자주 실행하는 걸 막는 기술.

  • 쓰로틀링: 일정 시간마다 한 번만 실행.
    ⏱️ 예: 스크롤 이벤트 (스크롤할 때마다 무조건 실행 ❌)
  • 디바운싱: 마지막 동작만 실행.
    ⌨️ 예: 검색창 타이핑 → 다 치고 나서만 자동완성 실행.

🔁 계속 일어나는 이벤트면 → 쓰로틀링,
🕒 마지막 입력만 중요하면 → 디바운싱

3. 자바스크립트의 호이스팅에 대해 설명해주세요.

호이스팅에 대해 이해하고 있고, 어떤 오류가 호이스팅 때문인가 구분할 수 있는지 확인하는 질문.

호이스팅의 영어 뜻은 바로 끌어올리다입니다. 그렇기에 자바스크립트의 호이스팅도 끌어올린다는 의미인데요. 바로 코드 실행 전에 변수 선언과 함수 선언을 스코프의 최상단으로 끌어올리는 것을 뜻합니다. 원래 C언어 같은 프로그래밍 언어를 사용했을 때는 변수나 함수가 무조건 상단에 선언이 되어 있어야 했습니다. 그래야 아래 줄에서 참조가 가능하니깐요. 하지만 자바스크립트는 실제로 선언된 위치와 상관 없이 최상단으로 선언부가 끌어올려지기에 선언 위치 앞에서도 호출이 가능해집니다.
다만 이게 함수, var, const/let의 경우에 따라 달라지는데요. 함수의 경우에는 어디서든 호출이 가능하고 제대로 작동도 합니다. 하지만 var의 경우에는 선언 전에 호출한다면 undefined를 반환하게 됩니다. 그러나 이게 오히려 오류를 안 내서 불편한 나머지 const/let은 선언 전에 호출하면 에러를 내보내게 되었습니다. 물론 에러는 내보내지만 호이스팅이 되지 않은 건 아니란 점에 주의해야 합니다.

  • 코드 실행 전에, 선언된 것들을 위로 끌어올림.
  • var는 선언만 끌어올려서 → 값은 undefined.
  • let, const도 끌어올리긴 하는데 → 선언 전에 쓰면 에러.
  • 함수는 전체가 끌어올려져서 → 어디서든 호출 가능.

호출이 위에 있는데 선언이 아래인데도 작동하는 건 이 때문

4. 이벤트 버블링과 캡처링에 대해 설명해주세요.

버블링과 캡처링으로 이벤트를 제어할 수 있는지 확인하는 질문
이름에서 오는 뜻을 활용하세요.

이벤트 버블링과 캡처링은 모두 이벤트가 전파되는 방식을 뜻합니다. 다만 서로 그 방향이 다를 뿐입니다.
버블링부터 말씀드리자면, 버블링은 거품이지 않습니까? 마치 거품이 수면으로 떠올라가듯이 이벤트가 전파되는 겁니다. 그래서 하위 요소에서 상위 요소로 이벤트가 전파되는 것을 버블링이라고 합니다.
반대로 캡처링은 포착한다고 생각하시면 됩니다. 마치 카메라가 내가 보는 시야의 일부분을 포착해서 담듯이 이벤트가 전파되는 겁니다. 그래서 이번엔 상위 요소에서 하위 요소로 이벤트가 전파되는 것을 캡처링이라고 합니다. 이러한 특성을 잘 활용한다면 이벤트 위임을 구현할 수 있습니다.

이벤트가 일어날 때, 어떻게 전파되느냐의 차이.

  • 버블링: 아래(자식) → 위(부모)로 올라감.
    버블처럼 위로.
  • 캡처링: 위(부모) → 아래(자식)로 내려감.
    📸 먼저 포착하고 내려옴.

    대부분 브라우저는 버블링 기본. 필요할 때 캡처링 사용 가능.

        

5. 이벤트 위임에 대해 설명해주세요.

이벤트 버블링과 캡처링에 대해 잘 이해하고 있는지 재확인 및 위임을 이용해 최적화를 할 수 있는지 확인하기 위한 질문
최적화 얘기를 하면 좋습니다.

이벤트 위임은 하위 요소의 이벤트를 상위 요소로 위임하는 걸 뜻합니다. 하위 요소가 많을 경우, 이러한 모든 요소들에 이벤트를 등록하고 관리하는 건 힘든 일이 될 수 있습니다. 그래서 버블링과 캡처링을 활용해 상위 요소에 이벤트를 위임하고, 이벤트 함수 내에서 하위 요소를 판단하여 이벤트를 처리하면 성능을 최적화할 수 있는 장점을 가진 게 바로 이벤트 위임입니다.

  • 많은 자식에게 각각 이벤트 달지 말고,
    부모 하나에만 달고 버블링으로 처리하는 방법.
  • 성능 좋아지고 유지 보수 쉬워짐.

예: ul에서 각 li 클릭 처리할 때 → ul에 이벤트 하나만 걸기

6. 자바스크립트의 this가 어떤 값을 가지는지 각 상황을 가정하여 설명해주세요.

각 상황에 따라 this의 변화를 이해하고 있는지 확인하기 위한 질문
암기 질문과 다름 없습니다. 외워오세요.

모범 답안: this 는 호출되는 상황마다 서로 다른 값을 참조하고 있어 혼동하기 쉬운 값입니다. 우선 일반 함수를 호출할 때는 전역 객체인 window를 뜻합니다. 그리고 객체의 메서드를 호출할 때에는 해당 객체를 의미합니다. 이어서 콜백 함수는 전달하는 곳은 상관이 없고, 함수가 실제로 호출되는 상황에 따라 달라집니다. 만약 호출하는 상황이 일반 함수라면 전역 객체를 가리키겠죠? 마지막으로 화살표 함수는 생성된 함수의 스코프에 따라 달라집니다. 예를 들어 객체의 메서드에서 화살표 함수를 만들어서 this를 호출했다면 생성된 함수의 스코프는 객체 스코프이므로 여기서 this는 객체를 뜻하게 됩니다. 이러한 this의 특징 때문에 call, apply, bind 같은 걸로 this를 고정시켜주기도 하지만, 저는 저포함 동료 분들의 혼선을 피하기 위해 this의 사용을 좀 지양하는 편입니다.

  • 상황에 따라 달라짐 💡 this = 호출한 놈
상황this가 가리키는 것
일반 함수window (엄격모드에선 undefined)
객체의 메서드객체
이벤트 핸들러이벤트를 건 요소
화살표 함수바깥 this 그대로 씀
bind, call, apply강제로 바꾼 그 값

⚠️ 그래서 화살표 함수는 this로 혼동 없어서 자주 씀

7. 자바스크립트의 프로토타입의 역할을 설명해주세요.

ES6 이전에 많이 쓰이던 프로토타입에 대해서도 인지하고 있는지 확인하는 질문.
설마 이런 거까지 알겠어?

모범 답안: 자바스크립트의 프로토타입은 객체가 가진 기본 속성과 메서드를 정의하는 객체입니다. 프로토타입에 정의된 이러한 속성과 메서드가 각 타입을 타입답게 만들게 됩니다. 예를 들어 숫자에 toString()메서드가 있는 것처럼 말입니다. 옛날에 클래스가 나오기 전에는 이 프로토타입을 통해 직접 메서드를 만들어주고는 했습니다.

  • 객체들이 공통으로 공유하는 기능(메서드) 저장소.
  • 예: 모든 배열에는 map, filter 같은 함수 있음 → Array.prototype에 있음.
  • 직접 확장도 가능:
Array.prototype.sayHi = () => console.log('hi');

클래스 나오기 전엔 이걸로 직접 상속 만들고 했음

8. 자바스크립트의 객체는 참조에 의해 복사됩니다. 이로 인해 생길 수 있는 오류와, 해당 오류를 피하는 방법을 설명해주세요.

참조에 의한 접근과 값에 의한 접근을 구분할 수 있는지 확인하는 질문입니다.
객체를 참조가 아닌 값으로서 복사하는 방법도 소개하면 좋습니다.

네, 여기서 참조에 의한 복사가 일어나는 이유는 값 자체를 복사해 주는 게 아니라 값이 들어있는 메모리 주소를 복사해서 주기 때문입니다. 그렇기에 객체를 복사하게 되면 서로 같은 메모리 주소를 가리키게 되어 한쪽이 값을 바꾸면 다른 쪽이 보여주는 값도 바뀌게 되는 겁니다. 이러한 특징 때문에 여러 오류가 생기곤 합니다. 그래서 깊은 복사를 통해 객체 또한 값으로서 복사하도록 하는 방법들이 있는데 대표적으로는 JSON.stringify()를 통해 객체를 문자열로 바꾸어서 복사하는 방법이 있고, 비교적 최근에 나온 structuredClone()을 사용하는 방법이 있습니다. 개인적으로는 후자가 더 짧고 쉽기 때문에 더 애용하는 편입니다.

  • {} 같은 객체를 복사하면, 값이 아닌 주소가 복사됨.
  • 그래서 하나를 바꾸면 다른 것도 바뀜.
  • 막으려면 깊은 복사 필요:
    - JSON.parse(JSON.stringify(obj))
    - structuredClone(obj) (최신 방법)

❌ 얕은 복사 (...obj)는 중첩 객체까지는 안 복사됨

9. 자바스크립트의 nullish 값은 무엇이 있을까요?

nullish로 평가되는 데이터 타입과 값의 종류를 이해하고 있는지 확인
nullish 병합 연산자를 언급하면 좋습니다.

네 자바스크립트에서 nullish는 말 그대로 null과 같은 값을 뜻합니다. 이에 대한 예시로는 대표적으로 nullundefined가 있습니다. 여기서 알고 넘어가면 좋은 게 있는데, 바로 nullish 병합 연산자입니다. 기존에는 || 를 이용해서 병합을 구현했는데요. 이렇게 되면 0이나 ''처럼 빈 문자열 등이 false로 평가되어 제대로 동작하지 않을 가능성이 생기곤 합니다. 그때 바로 물음표 2개를 붙인 ??로 대체해준다면 nullish한 값에 대해서만 병합을 실행하게 됩니다.

  • nullundefined
  • 그래서 ?? 연산자에서:
null ?? '대체값' // 👉 '대체값'
0 ?? '대체값' // 👉 0 (nullish가 아니니까!)
기존 ||0이나 빈 문자열도 false로 처리해서 문제가 있었음

기존 ||는 0이나 빈 문자열도 false로 처리해서 문제가 있었음

10. =====의 차이점은 무엇일까요?

자바스크립트의 기본 문법을 확인하는 질문입니다.
nullish와 연계하여 대답하면 좋습니다.

비교할 때 판단이 다릅니다. 간단히 요약하자면 ==는 타입은 다르지만 값이 같을 때, 예를 들어 문자열 1과 숫자 1을 비교하면 같다고 뜰 겁니다. 그래서 숫자 0과 nullish 값을 이 연산자를 이용해 비교하면 true가 떠서 같다고 나올 겁니다. 그리고 ===는 좀 더 엄격하게 타입과 값을 모두 비교합니다. 그래서 문자열 1과 숫자 1을 비교하면 다르다고 뜰 것입니다. 저는 보통 엄격한 비교를 위해 ===를 더 선호해 사용하는 편입니다.

  • ==: 값만 비교. 타입 자동 변환함.
    - '1' == 1 👉 true
    - 0 == '' 👉 true
  • ===: 값 + 타입 완전 일치해야 true

안전하게 쓰려면 무조건 === 쓰는 게 낫다

0개의 댓글