Interview
Interview Retrospecting (1)
사실 기술면접 스터디를 한동안 진행했었는데, 최근 한달정도 쉬는 텀을 가지고 있었다. 그러던 중, 오늘 실제로 기술면접을 보게 되었다. 하지만 생각보다 만족스러운 답변을 드리지 못한 질문들이 꽤 있어서 기억을 더듬어가며 정리해본다.
목차
- var, let, const
- primitive types & structured types
- map & forEach
- arrow function
- 기본적인 자바스크립트의 원리(내용이 길어서 따로 포스팅)
- 함수형 컴포넌트를 더욱 사용하는 이유
- 매개변수로 받은 배열에 대해 함수 안에서 push 메소드를 쓰게 되면?
- 타입스크립트에서 any를 사용해야하는 상황?
- any로 인해 생기는 사이드이펙트는 어떻게 처리 해야하는가? (추후에 따로 포스팅)
생각보다 정리하고 싶은 내용이 많아서 두개의 포스트로 나누어서 정리함.
1. Var, Let, Const
JavaScript 에서 변수 선언은 var, let, const 세가지 키워드를 사용하는 방법이 있다.
1-1. var 키워드를 사용하여 변수를 선언할 경우 주의해야할 점들
- var 키워드는 변수명이 중복적으로 선언 가능하다.
- var 키워드는 변수의 키워드를 사용하지 않아도 암묵적으로 변수 생성하지 않기 때문에 전역의 범위 오염될 수 있다.
- var 키워드 함수(function)의 범위만 인정한다.
- if, for문 같은 블럭문 같은 경우에는 범위가 유효하지 않다.
- var 키워드는 사용할 경우 호이스팅에 의해 선언하기 이전에 참조할 수 있다.
- ES6+ 문법에서 변수의 키워드 let, const가 나오면서 var 키워드를 사용하여 변수를 선언하는 방법은 가급적 권장하지 않는다.
1-2. let 변수 키워드
- let 키워드로 이름이 같은 변수를 중복 선언하면 문법 에러가 발생한다.
- let 키워드로 선언한 변수는 모든 코드 블록(함수, if 문, for 문, while 문, try/catch 문 등)을 지역 스코프로 인정하는 블록 레벨 스코프를 따른다.
- let 키워드로 선언한 변수는 "선언 단계" 와 "초기화 단계"가 분리되어 진행된다.
- let 키워드로 선언한 변수는 스코프의 시작 지점부터 초기화 단계 시작 지점(변수 선언문)까지 변수를 참조할 수 없다.
- 스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간을 일시적 사각지대라고 부른다.
1-3. const 변수 키워드
- const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화해야 한다.
- let 키워드로 선언한 변수와 같이 블록 레벨 스코프를 가진다.
- var, let 키워드로 선언한 변수와 달리 재할당이 금지된다(상수).
- const 키워드로 선언된 변수에 객체를 할당할 경우 변경할 수 있다.변경 가능한 값인 객체는 재할당 없이도 직접 변경이 가능하기 때문이다.
요약
let이나 const로 선언한 변수는 var로 선언한 변수와 달리 블록 레벨 스코프를 따르고 const로 선언한 변수는 let, var로 선언한 변수와는 달리 재할당이 금지된다.
2. Primitive types & Structured types
자바스크립트에서 값은 원시값과 참조값으로 나뉜다.
원시값
원시값은 단순한 데이터이다.변수에 할당 될 때 메모리 상에 고정된 크기로 저장되고, 해당 변수가 원시 데이터 값을 보관한다.
변수에 저장된 실제 값을 직접 접근한다.
ex : Number, String , Boolean, null, undefined, BigInt, Symbol
let x = 100; let y = x; x = 99; y; // 100;
각 변수간의 원시값을 복사할 경우 데이터의 값이 복사된다.
참조값
여러 값으로 구성되는 메모리에 저장된 객체이다.크기가 정해져있지 않고, 변수에 할당 될 때 값이 직접 해당 변수에 저장될수 없으며, 변수에는 데이터의 대한 참조만 저장된다.자바스크립트는 메모리 위치에 직접 접근하는 것을 허용하지 않기에 객체의 메모리 공간을 직접 조작하는 것은 불가능하다.
객체를 조작할 때는 객체 자체가 아니라 해당 객체에 대한 참조를 조작하는 것이다.
ex : Object, Array, Function
let x = {const: 100}; let y = x; x.count = 99; y.count; // 99
x와 y는 동일한 참조를 담고 있으며, 따라서 동일한 데이터를 가리킨다.
3. Array.forEach VS Array.map
3-1. Array.forEach()
array.forEach() 메서드는 주어진 배열 요소 각각에 대하여 실행한다.
- array.forEach()는 배열 전체를 순회하므로 중간에 순회하는 걸 멈출 수(break) 없다.
// Syntax array.forEach(callback(currentValue[index[, array]])[thisArg]) //----------------------------------------------------------------- // callback : 각 요소에 대해 실행할 함수는 세 가지 매개변수를 받는다. // currentValue : 처리할 현재 요소 // index(option) : 처리할 현재 인덱스 // array(option) : map를 호출한 배열 // thisArg(option) : callback을 실행할 때 this로 사용할 값
3-2. Array.map()
- array.map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다.
// Syntax array.map(callback(currentValue[, index[, array]])[, thisArg]) //----------------------------------------------------------------- // callback : 각 요소에 대해 실행할 함수는 세 가지 매개변수를 받는다. // currentValue : 처리할 현재 요소 // index(option) : 처리할 현재 인덱스 // array(option) : forEach를 호출한 배열 // thisArg(option) : callback을 실행할 때 this로 사용할 값
요약
즉, array.forEach()는 반환된 결과를 따로 모아서 처리하는 값이 없기 때문에 return을 사용하게 되면 undefined가 할당된다.
4. Array Function
화살표 함수(Arrow Function)는 함수의(Function)키워드를 간단히 사용할 수 있게 ES6+에서 추가된 문법이다.
4-1. 화살표 함수의 this
일반 함수와 화살표 함수의 차이점은 this키워드다.
- 일반 함수에서 this는 함수의 호출 방식에서 달라진다.
- 화살표 함수에서 this는 정의되지 않기 때문에 this에 접근하려고 하는 경우에 스코프 페인 가장 가까운 this에 접근하게 된다.
const person = { name: 'Print', sayHi: () => console.log(`Hi ${this.name}`) }; person.sayHi(); // Hi undefined
4-2. 화살표 쓰면 안되는 경우
- 객체의 메서드(method)로 화살표 함수를 사용하게 되면 가까운 this를 찾기 때문에 undefined가 출력된다.
- protype에 할당할 경우에 위와 같은 이유로 undefined를 출력하게 된다.
- 생성자 함수(constructor function)에서 this는 새롭게 만들어질 객체를 가리키지만, 화살표 함수를 생성자 함수로 사용하게 되면 타입 에러가 발생하게 된다.
- addEventListner의 콜백함수에서 화살표 함수를 사용하면 this는 전역 객체 window를 가리키게 된다.
요약
즉, 화살표 함수는 짧은 함수를 작성하거나, 컨텍스트가 없는 짧은 코드를 담을 용도로 만들어졌다.
6. 함수형 컴포넌트를 선호하는 이유
React 컴포넌트를 만들때 클래스형 컴포넌트, 함수형 컴포넌트 2가지 방식이 있다
과거에는 클래스형 컴포넌트를 많이 사용했지만 2019년 v16.8 부터 함수형 컴포넌트에 리액트 훅(hook)을 지원해 주어서 현재는 공식 문서에서도 함수형 컴포넌트와 훅(hook)을 함께 사용할 것을 권장하고 있다.
요즘은 많은 개발자들이 클래스형 컴포넌트보다 함수형 컴포넌트+Hook을 사용한다. 클래스형 컴포넌트는 로직과 상태를 컴포넌트 내에서 구현하기 때문에 상대적으로 복잡한 UI 로직을 갖고 있는 반면, 함수형 컴포넌트는 state를 사용하지 않고 단순하게 데이터를 받아서(props) UI에 뿌려준다. Hook들을 필요한 곳에 사용하며 Logic의 재사용이 가능하다는 장점이 있고 클래스형 컴포넌트보다 선언하기가 좀 더 편하고, 메모리 자원을 덜 사용한다는 장점이 있어서 함수형 컴포넌트+Hook을 주로 사용한다.
더욱 구체적인 차이점은 추후 포스팅
7. 타입스크립트에서 any를 사용해야하는 상황
7-1. any 타입이란?
타입스크립트에서 any는 어원 그대로 any를 타입으로 선언한 곳에는 어떤 타입이든 올 수 있다는 것을 의미한다.
let a: any = 'string'// any타입에 string 할당 가능let b: any = ['array']// any타입에 Array 할당 가능let c: any = a + b// string과 Array를 더하고 있지만 에러가 발생하지 않음.
타입스크립트에서 컴파일 할때 모든 변수에는 타입이 있어야 한다. 이때 타입을 지정해주지 않거나 값이 명확하지 않은 상황에서는 any를 기본타입으로 가정한다.
7-2. any 타입 선언을 지양해야 하는 이유.
any를 선언하면 어떤 타입이든 넣을 수 있기 때문에 간편해 보이지만 필수적인 상황이 아니라면 사용하지 않는 것이 좋다.
any를 선언하면 javascript처럼 코드가 어떤 연산을 할지, Number 타입이 Array관련 함수를 호출하는지 예측할 수 없게되고 프로그램의 안정성을 떨어뜨리게 된다.
7-3. any 타입을 사용해야 하는 상황과 에러 검출
any의 사용을 지양해야하지만, 어떤 타입의 값이 들어올 줄 모르고, 타입을 선언하기 어려운 케이스라면 그때는 any와 같이 모든 타입의 값을 받을 수 있는 unknown 타입을 지정해 주는 것이 좋다.
8. any로 인해 생기는 사이드이펙트는 어떻게 처리 해야하는가?
어떻게 해야 하는지 모르겠다. 추후에 포스팅
# CS# FE-Developer# interview