JavaScript와 가까워지기 위해서 모던 자바스크립트 Deep Dive 책도 읽어보고, 코어 자바스크립트도 읽어보았지만... 역시 읽는 것으로 그치는게 아닌 이해하고, 용어와 익숙해지고, 말로 뱉을 수 있는 게 중요하다는 것을 면접을 통해서 항상 깨닫습니다. 그래서 면접에서 받았던 기술 질문들과 손코딩을 잊지 않기 위해 기록해보려고 합니다.
let, const, var 키워드 질문은 진짜 단골 질문인 것 같다.
호이스팅, this, arguments, 생성자 함수의 차이가 있다.
화살표 함수를 사용할 경우, 표현식을 이용하기 때문에 호이스팅이 발생하지 않는 것처럼 보인다.(선언 이전에 참조, 호출할 수 없음)
일반 함수 중에서도 함수 선언문으로 선언할 경우에는 호이스팅이 발생하여 선언 이전에 호출이 가능하다. (함수 표현식의 경우 선언 이전에 참조, 호출할 수 없음)
일반 함수에서는 arguments 객체를 참조할 수 있지만, 화살표 함수에서는 arguments 객체를 참조할 수 없다. 대신 rest parameter(...)
를 사용할 수 있다.
일반함수로 호출하면 this에는 전역 객체가 바인딩 된다. (생성자 함수로 호출할 경우 생성할 인스턴스 바인딩, 메서드의 경우 메서드를 호출한 객체에 바인딩)
화살표 함수의 경우는 언제나 상위 스코프의 this를 가리킨다.
일반 함수는 생성자 함수로서 사용할 수 있지만, 화살표 함수는 생성자 함수로서 사용할 수 없다.
외부 함수보다 중첩 함수가 더 오래 유지되는 경우, 중첩 함수는 이미 생명 주기가 종료된 외부 함수의 변수를 참조할 수 있는데 이런 중첩함수를 클로저라고 한다.
클로저는 상태가 의도치 않게 변경되지 않도록 상태를 안전하게 은닉하고 특정 함수에게만 상태 변경을 허용하기 위해 사용한다.
function outer() {
const a = 'a';
const b = 'b';
function inner() {
const a = 'inner-a';
console.log(a);
console.log(b);
}
return inner;
}
const closurePattern = outer();
closurePattern();
interface IUser {
name: string;
age: number;
}
type TUser = {
name: string;
}
interface IUser {
name: string;
}
interface IUser {
age: number;
}
const user: IUser = {
name: 'sejin',
age: 29,
}
type TUser = {
name: string;
}
type TUser = {
age: number
}
// Duplicate identifier 'TUser'. 에러 발생
&
intersection을 통해서 확장시킬 수 있다.interface IPerson {
person: boolean;
}
interface IUser extends IPerson {
name: string;
age: number;
}
type TPerson = {
person: boolean;
}
type TUser = TPerson & {
name: string;
age: number;
}
fetch로 변경사항을 먼저 확인한 후, pull을 받아주는 방법이 안전함
알고리즘 문제는 총 3문제였으나, 세 번째 문제를 풀려고 하는 찰나 끝나서 문제가 기억이 나질 않는다. 그렇기 때문에 기억이 나는 2문제라도 적어보려고 한다.
최소 공배수를 구하는 함수를 만들어보자.
function calculateMin(a, b) {
if (a < 0 || b < 0) {
return
}
if (a < b) {
return (a * b) / b
} else {
return (a * b) / a
}
}
console.log(calculateMin(3, 5));
function calculateMin(a, b) {
if (a < 0 || b < 0) {
return
}
if (a > b && a % b === 0
) {
console.log((a * b) / b);
} else if (a < b && b % a === 0) {
console.log((a * b) / a);
} else {
console.log((a * b) / 1);
}
}
a = b * q + r
(a, b) = (b, r)
// 최대공약수 greatest common divisor
// 최소공배수 least common multiple
function calcLCM(a, b) {
function calcGCD(x, y) {
// 나머지가 0이었을 때, x가 최대공약수가 됨
if (y === 0) {
return x;
} else {
return calcGCD(y, x % y);
}
}
const gcd = calcGCD(a, b);
const lcm = (a * b) / gcd;
return lcm;
}
calcLCM(3, 5); // 15
calcLCM(12, 28); // 84
1부터 100까지 담긴 배열 n이 있다. 배열의 요소 중 숫자 3의 배수는 'Fizz', 5의 배수는 'Buzz', 3과 5의 배수는 'FizzBuzz'를 출력하도록 만들어보자.
// 1부터 100까지 담긴 배열 n이 있다고 가정
for (i = 0; i < n.length; i++) {
if(n[i] % 3 === 0) {
console.log('Fizz');
} else if (n[i] % 5 === 0) {
console.log('Buzz');
} else if (n[i] % 15 === 0) {
console.log('FizzBuzz');
}
}
// 1부터 100까지 담긴 배열 n이 있다고 가정
for (i = 0; i < n.length; i++) {
if(n[i] % 15 === 0) {
console.log('FizzBuzz');
} else if (n[i] % 3 === 0) {
console.log('Fizz');
} else if (n[i] % 5 === 0) {
console.log('Buzz');
} else {
console.log(n[i])
}
}
// 1부터 100까지 담긴 배열 n이 있다고 가정
for(let i = 0; i < n.length; i++) {
n[i] % 15 === 0
? console.log('FizzBuzz')
: n[i] % 3 === 0
? console.log('Fizz')
: n[i] % 5 === 0
? console.log('Buzz')
: console.log(n[i])
}