JavaScript Q&A
1. 스코프에 대해서 설명하세요.
- 변수를 탐색(참조)할 수 있는 유효 범위
- 전역 스코프는 최상단의 스코프로써 이곳에서 선언된 변수는 전역 변수이고, 어떤 영역에서든 접근이 가능.
- 지역 스코프에 선언된 변수는 지역 변수이며, 해당 스코프와 하위 지역(중첩 함수)에서는 탐색이 가능하지만 더 상위 지역에서는 탐색이 불가능.
2. 클로져에 대해서 설명하세요.
- 외부의 변수를 품고 있는 즉, 자신이 생성될 때의 렉시컬 환경을 기억하는 함수.
- 이러한 현상이 나오는 이유는 함수가 호출되고 실행이 완료되어 함수가 스택에서 제거되더라도 이를 참조하는 대상이 남아있기 때문에 가비지 컬렉터에 의해 메모리 정리가 되지 않아 발생.
3. 클로져의 사용 예제를 알려주세요.
- 캡슐화를 통해 변수를 private 하게 사용 가능
- 또한, 여러 개의 인자를 가진 함수가 있을 때, 각각의 인자를 따로 받는 함수를 만드는 커링 기법을 이용하여 마치 템플릿 함수처럼 사용할 수 있고, 고정값을 넣어 재사용할 수도 있음.
4. 변수 선언, 초기화, 할당의 차이점에 대해서 설명하세요.
- 변수 선언은 실행 컨텍스트의 변수 객체에 변수를 등록하는 단계. (이 변수 객체는 스코프가 참조하는 대상이며, 이 단계에서 호이스팅이 일어남.)
- 초기화는 실행 컨텍스트에 존재하는 변수 객체에 선언 단계의 변수를 위한 메모리를 만드는 단계.
- 할당은 초기화된 메모리에 다른 값을 넣는 것을 뜻함.
5. 호이스팅과 Temporal Dead Zone이 어떻게 연관되어 있는지 설명하세요.
- 우선 초기화되지 않는 변수가 있는 곳을 tdz라고 하는데, 변수가 초기화되는 순간 tdz에서 나오게 되며 사용할 수 있는것이다.
- 호이스팅은 선언되지 않은 함수, 변수등을 상단으로 끌어올려 사용할 수 있게 하는 방식인데, 연관성 예시로 var / let이 있음.
- 변수의 경우 크게 선언 -> 초기화 -> 할당의 라이프사이클을 가지는데, var의 경우에는 선언과 동시에 undefined으로 초기화를 진행하기 때문에 undefined으로 호이스팅됨.
- 호출부가 선언부보다 위에 있을 경우에 let의 경우에는 선언과 초기화가 분리되어 그 사이에 tdz가 생성되기 때문에 접근할 수 없어 참조 에러가 남.
- 이처럼 tdz가 호이스팅되어 나타날 수 있는 의도치 않은 결과를 막아준다 라고 이야기할 수 있음.
6. ES6의 주요 변화점에 대해서 설명하세요.
- class를 도입 → 객체지향프로그래밍
- 기존 var의 함수레벨 스코프에서 let, const를 추가 → 블록레벨 스코프를 이용하여 변수의 혼란을 줄임
- 백 틱(`)과 ${}를 이용한 템플릿 리터럴 표기법이 추가.
- 또한, arrow function을 통해 함수를 더 간편하게 활용할 수 있게 되었고, 비구조화 할당을 통해 배열로 묶어서 변수를 선언하거나 변수를 전달 받을 수 있고, 매개 변수의 기본값을 정의해주는 default parameter, 매개변수를 배열로 묶어주는 rest parameter, 배열을 "..."을 이용하여 원소로 해체해주는 spread syntax 문법이 생김.
- for ... of, 반복 가능한 객체에서 그 길이에 맞게 각 속성값에 대한 반복문을 실행하는 문법도 도입.
7. 원시 자료형, 참조 자료형
- 원시 자료형 - 변경 불가능한 값
- 변수가 할당될 때, 메모리의 고정 크기를 값으로 저장하고 해당 주소를 직접 참조
- 참조 자료형 - 변경 가능한 값
- Heap 영역에 변수 생성, 값이 할당된 메모리의 주소를 참조.
8. == vs ===
- == : 암묵적 타입 변환으로 타입을 일치시킨후 비교 (느슨한 비교)
- === : 값과 타입을 모두 고려하여 동등함을 비교 (엄격한 비교)
9. 자바스크립트에서 배열의 타입
- object, 객체 → 쉽게 말하면 하나의 데이터 덩어리
- 일반적인 배열이라는 자료구조의 개념은 동일한 크기의 메모리 공간이 빈틈없이 연속적으로 나열된 자료구조
- 배열의 요소 → 하나의 타입으로 통일되어 있으며 서로 연속적으로 인접해있음. (밀접 배열, dense array)
- but, JS에서의 배열은 배열의 요소를 위한 각각의 메모리 공간은 동일한 크기를 갖지 않아도 되며 연속적으로 이어져있지 않을 수도 있다. (희소 배열, sparse array)
- JS에서의 배열은 일반적인 의미의 배열이 아니며, 배열의 동작을 흉내낸 특수한 객체임
- 구조 : 인덱스를 프로퍼티 키로 갖으며, length 프로퍼티를 갖는 특수한 객체. 배열의 요소는 사실 프로퍼티의 값
일반적인 배열과 JS 배열의 장단점
- 일반적인 배열은 인덱스로 배열요소에 빠르게 접근 가능(O(1)), 하지만 특정 요소를 탐색하거나 삽입 또는 삭제하는 경우 효율적이지 않음.
- JS 배열은 hash table로 구현된 객체, 인덱스로 배열요소에 접근하는 경우 일반적인 배열보다 성능적으로 느림, 하지만 특정 요소를 탐색하거나 삽입 또는 삭제하는 경우 빠른 성능을 기대할 수 있음.
10. undefined와 null 그리고 undeclared의 차이
- undefined - 선언이후 값이 할당되지 않은 상태
- null - 값이 없다는 것을 명시
- undeclared - 선언도 할당도 되어있지 않을때
11. rest parameters와 spread syntax
- rest parameters는 매개 변수 이름 앞에 세개의 점을 붙여 정의한 매개 변수를 의미.
- 함수로 전달된 인수들의 목록을 배열로 만들 때 사용. 여러 매개 변수를 사용할 시에는 반드시 마지막 파라미터로 사용해야 함.
- spread syntax는 점 세개를 이용하여 배열같이 여러개의 값들을 각 원소로 표현해줄 때 사용. iterable하지 않은 객체에서는 사용할 수 없음.
12. 깊은 복사와 얕은 복사의 차이에 대해서 설명하세요. 자바스크립트에서 깊은 복사를 하는 방법은 무엇인가요?
- 객체의 모든 프로퍼티가 원시값인 경우 얕은 복사
- 어떤 프로퍼티가 다른 객체에 대한 참조 값일 경우? → 얕은 복사를 할 경우에는 해당 프로퍼티는 같은 객체에 대한 참조값을 공유하게 될 것이므로 복제가 되었다 볼 수 없음. → 얕은 복사본은 중첩 객체를 처리할 수 없다.
- 이 경우에는 key의 각 값을 검사하면서, 그 값이 객체인 경우 객체의 구조도 복사해주는 반복문을 사용해야 함
lodash
라이브러리의 메서드인 _.cloneDeep(obj)
를 사용 가능.
13. let, const, var의 차이와 각각의 사용 방법을 설명하세요.
- var : 중복선언 가능, 재할당 가능, 함수레벨 스코프
- let : 중복선언 불가, 재할당 가능, 블록레벨 스코프
- const : 중복선언 불가, 재할당 불가, 블록레벨 스코프 (상수로 다루자)
14. 순수함수란 무엇인가요?
- 순수 함수란 오직 함수의 입력만이 함수의 결과에 영향을 주는 함수를 의미.
- 외부 상태에 의존하지 않고, 오직 매개 변수를 통해 함수 내부로 전달된 인수에만 의존해 반환 값을 만듬.
- 또한, 매개 변수로 전달된 값을 수정하지 않음.
순수 함수의 조건
- 동일한 인자 값을 받으면 항상 동일한 return 값을 반환.
- 어디서 호출되든 동일한 결과
- 외부에 영향을 주지도 받지도 말아야 함.
