프론트엔드 기술 문제

게으른개발자·2020년 6월 24일
6

면접준비

목록 보기
3/6

1. window 객체가 무엇일까요?

브라우저 객체 모델(BOM)의 핵심이자 브라우저의 인스턴스

브라우저 객체 모델(BOM)이란, 브라우저 창에서 접근하고 조작할 수 있게 하는 인터페이스

브라우저 객체 모델(BOM)은 브라우저 창과 보이는 영역인 window를 기반으로 만들어진다.
window 객체 모든 객체의 최상위에 존재하기 때문이다. 브라우저의 모든 요소들과 자바스크립트 엔진, 변수들은 모두 window 객체에 담겨져있다.

DOM이란?

Document of Model의 약자.
javascript에서 doument로 접근 가능. 자식의 최상의 문서는 html

Doctype이란?

문서 형식 선언으로, 문서 상단에 1회 선언돠며 브라우저 랜더링 또는 유효성 검사시 문서 형식을 확인하는데 쓰인다.

2. 브라우저의 렌더링 과정에 대해서 상세하게 설명하라

브라우저의 역할은 사용자의 요청을 서버에 전달하고 그 결과를 화면에 나타내는 과정인데 렌더링은 화면에 나타내는 과정을 의미한다.

더 상세하게 알아보면,

  1. DOM 생성
  2. CSSOM (CSS Object Model) 생성
  3. Render Tree 생성
  4. Render Tree 배치
  5. Render Tree 그리기 이러한 과정을 통해 브라우저가 서버에 요청한 내용의 노드들을 픽셀화 시키는 것을 브라우저 렌더링 이라고 한다.

3. 익명 함수의 일반적인 사용 사례는 무엇인가요?

  • 익명 함수는 IIFE로 사용되어 지역 범위 내에서 일부 코드를 캡슐화 하므로 선언된 변수가 전역 범위로 누출되지 않는다
  • 한 번 사용되고 다른 곳에서는 사용할 필요가 없는 콜백으로 사용된다
  • 함수 본체를 찾기 위해 다른 곳을 찾아볼 필요 없이 코드를 호출하는 코드 바로 안에 핸들러가 정의되어 있으면 코드가 보다 독립적이고 읽기 쉽게 보인다

4. 실행 컨텍스트(Execution Context)에 대해 설명하라*

자바스크립트의 코드들이 실행되기 위한 환경

전역 컨텍스트, 함수 컨텍스트 2가지 존재

  1. 전역 컨텍스트 하나 생성 후에 함수 호출할 때마다 함수 컨텍스트가 생성
    컨텍스트를 생성시에 변수객체, 스코프 체인, this가 생성됨
  2. 컨텍스트 생성 후 함수가 실행되는데 사용되는 변수들은 변수 객체 안에서 값을 찾고 없다면 스코프체인을 따라 올라가며 찾음
  3. 함수 실행이 마무리되면 해당 함수 컨텍스트는 사라짐. 페이지가 종료되면 전역 컨텍스트가 사라짐

즉, 자바스크립트의 코드가 실행되기 위해서는 변수객체, 스코프체인, this 정보들을 담고 있는 곳을 실행컨텍스트라고 부른다.


2020년 6월27일 추가

ECMAScript 스펙에 따르면 실행 컨텍스트를 실행 가능한 코드를 형상화하고 구분하는 추상적인 개념이라고 정의한다. 좀 더 쉽게 말하자면 실행 컨텍스트는 실행 가능한 코드가 실행되기 위해 필요한 환경 이라고 말할 수 있겠다.

물리적으로 가지는 3가지의 객체: Variable Object, Scope Chain, thisValue

Variable Object (변수객체)

Variable Object는 아래의 정보를 담는 객체이고, 실행 컨텍스트의 프로퍼티이기 때문에 값을 갖는데 이 값은 다른 객체를 가리킨다.

  • 변수
  • 매개변수(parameter)와 인수 정보(arguments)
  • 함수 선언(함수 표현식은 제외)

전역 컨텍스트의 경우
Variable Object는 유일하며 최상위에 위치하고 모든 전역 변수, 전역 함수 등을 포함하는 전역 객체(Global Object / GO)를 가리킨다. 전역 객체는 전역에 선언된 전역 변수와 전역 함수를 프로퍼티로 소유한다.

함수 컨텍스트의 경우
Variable Object는 Activation Object(AO / 활성 객체)를 가리키며 매개변수와 인수들의 정보를 배열의 형태로 담고 있는 객체인 arguments object가 추가된다.

Scope Chain (스코프체인)

전역 객체와 중첩된 함수의 스코프의 레퍼런스를 차례로 저장하고 있다.
다시 말해, 스코프 체인은 해당 전역 또는 함수가 참조할 수 있는 변수, 함수 선언 등의 정보를 담고 있는 전역 객체(GO) 또는 활성 객체(AO)의 리스트를 가리킨다.

실행 컨텍스트 자세한 내용!
실행 컨텍스트 간단한 내용!

5. 클로저(Closure)란 무엇이며, 왜 이러한 패턴을 사용하는가*

함수 안에 또 다른 함수를 정의 하고 사용하는 것

내부 함수가 자신이 선언 됐을 때의 환경인 스코프를 기억하여 외부 환경에서 호출되어도 그 환경에 접근할 수 있는 함수, 즉 자신이 생성될 때의 환경을 기억하는 함수

var base = 'Hello, ';
function sayHelloTo(name) {
  var text = base + name;
  return function() {
    console.log(text);
  };
}

var hello1 = sayHelloTo('승민');
var hello2 = sayHelloTo('흥민');
var hello3 = sayHelloTo('증민');
hello1(); // 'Hello, 승민'
hello2(); // 'Hello, 흥민'
hello3(); // 'Hello, 증민'

출력된 결과를 보면 text 변수가 동적으로 변화하고 있는 것처럼 보인다. 실제로는 text라는 변수 자체가 여러 번 생성된 것이다.
즉, hello1()hello2(), hello3()서로 다른 환경을 가지고 있고 클로저를 통해 각자의 환경을 기억하고 있다.

사용 하는 이유 :

  1. 현재 상태를 기억하고 변경된 최신 상태를 유지하기 위해
  2. 전역 변수의 사용을 억제 하기 위해
  3. 정보를 은닉하기 위해
  4. 실수를 줄이기 위해

2020년 6월28일 추가

var counter = function() {
  var count = 0;
  function changeCount(number) {
    count += number;
  }
  return {
    increase: function() {
      changeCount(1);
    },
    decrease: function() {
      changeCount(-1);
    },
    show: function() {
      alert(count);
    }
  }
};
var counterClosure = counter();
counterClosure.increase();
counterClosure.show(); // 1
counterClosure.decrease();
counterClosure.show(); // 0

counter 함수를 호출 할 때, counterClosure 컨텍스트에 counterClosure와 counter가 담긴 scope chain이 생성된다. 그렇게 되면 이제 counterClosure에서 계속 count로 접근할 수 있다. return 안에 들어 있는 함수들은 count 변수나, changeCount 함수 또는 그것들을 포함하고 있는 스코프에 대한 클로저라고 부를 수 있다.

6. 이벤트 루프에 대해서 설명, 동시성 모델에 대해서 설명하라*

  • 자바스크립트는 싱글 스레드 기반 언어이다.
  • 함수를 실행하면 함수 호출이 스택에 순차적으로 쌓이고 스택의 맨위에서부터 아래로 한번에 하나의 함수만 처리 할 수 있다.
  • 하지만, 자바스크립트에는 이벤트 루프라는것을 통해 동시성을 지원한다. (동시에 일어나는 것이 아니라 동시에 일어나는 것처럼 보이게 하는것이다!)
  • 이벤트 루프는 콜 스택에서 실행 중인 게 있는지 확인하고, Event queue에 작업이 있는지 확인해서 콜스택이 비어있다면 이벤트큐 내의 작업이 콜스택으로 이동되어서 실행된다.

7. 프로토타입이란?*

프로토타입을 기반으로 상속을 구현하여 불필요한 중복을 제거, 즉 코드의 재사용

생성자 함수가 생성할 모든 인스턴스가 공통적으로 사용할 프로퍼티나 메소드를 프로토타입에 미리 구현해 놓음으로써 또 구현하는것이 아니라 상위 객체인 프로토타입의 자산을 공유하여 사용한다.

__proto__로 자신의 프로토타입, 즉 Prototype 내부슬롯에 접근 할 수 있다.

프로토타입체인 이란?
1. 객체의 프로퍼티에 접근하려고 할때 객체에 접근하려는 프로퍼티가 없으면, __proto__가 가리키는 링크를 따라 자신의 부모역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색
2. 프로로타입체인의 최상위 객체는 Object.prototype이다. 이 객체의 프로퍼티와 메소드는 모든 객체에게 상속됨


2020년 6월28일 추가

  • constructor는 생성자 함수 그 자체를 가리킴
  • prototype은 생성자 함수에 정의한 모든 객체가 공유할 원형
  • __proto__는 생성자 함수를 new로 호출할 때, 정의해두었던 prototype을 참조한 객체
  • prototype은 생성자 함수에 사용자가 직접 넣는 거고, __proto__는 new를 호출할 때 prototype을 참조하여 자동으로 만들어짐
  • 생성자에는 prototype, 생성자로부터 만들어진 객체에는 __proto__
  • 따라서 사용자는 prototype만 신경쓰면 된다. __proto__는 prototype이 제대로 구현되었는지 확인용으로 사용한다.
function Ultra(){}
Ultra.prototype.ultraProp = true;
 
function Super(){}
Super.prototype = new Ultra();
 
function Sub(){}
Sub.prototype = new Super();
 
var o = new Sub();
console.log(o.ultraProp); // true

생성자 Sub를 통해서 만들어진 객체 o가 Ultra의 프로퍼티 ultraProp에 접근 가능한 것은 prototype 체인으로 Sub와 Ultra가 연결되어 있기 때문이다. 내부적으로는 아래와 같은 일이 일어난다.

  1. 객체 o에서 ultraProp를 찾는다.
  2. 없다면 Sub.prototype.ultraProp를 찾는다.
  3. 없다면 Super.prototype.ultraProp를 찾는다.
  4. 없다면 Ultra.prototype.ultraProp를 찾는다.

8. 자바스크립트에서 This는 몇가지로 추론 될 수 있는가*

  • 내부함수는 일반 함수, 메소드, 콜백 함수 어디에서 선언되었든지 this는 전역객체를 가르킴
  • 일반함수의 this는 window(전역)을 가르킴
  • 화살표 함수의 this는 언제나 상위스코프의 this를 가르킴

9. Call, Apply, Bind 함수에 대해 설명해달라

this가 함수 호출식에 따라 객체를 가르켰다면 call apply bind는 함수가 직접 실행 문맥을 결정한다. 그 중에 call, apply는 함수를 호출해 실행한다. call apply를 사용했을때의 장점은 첫번째 인자가 없더라도 에러없이 실행이 가능하다(자동으로 전역객체를 지정하여 실행) bind는 지정한 객체의 함수를 만든다. 정리하면 call apply는 함수를 실행시켜주는 것이고, bind는 새 함수를 만들어주는 것이다.

const obj = { name: 'Tom'};

const say = function(city) {
  console.log(`Hello, my name is ${this.name}, I live in ${city}`);
}

say('seoul'); // Hello, my name is , I live in seoul
say.call(obj, 'seoul'); // Hello, my name is Tom, I live in seoul
say.apply(obj, ['seoul']); // Hello, my name is Tom, I live in seoul

10. Scope Chain에 대해 설명하라

내부 함수에서는 외부 함수의 변수에 접근 가능하지만 외부 함수에서는 내부 함수의 변수에 접근할 수 없다. 그리고 모든 함수들은 전역 객체에 접근할 수 있다.

var name = 'zero';
function outer() {
  console.log('외부', name);
  function inner() {
    var enemy = 'nero';
    console.log('내부', name);
  }
  inner();
}
outer();
console.log(enemy); // undefined

inner 함수는 name 변수를 찾기 위해 먼저 자기 자신의 스코프에서 찾고, 없으면 한 단계 올라가 outer 스코프에서 찾고, 없으면 다시 올라가 결국 전역 스코프에서 찾음
전역 스코프에서 name 변수를 찾아서 'zero'라는 값을 얻음
만약 전역 스코프에도 없다면 변수를 찾지 못하였다는 에러가 발생

이렇게 꼬리를 물고 계속 범위를 넓히면서 찾는 관계를 스코프 체인이라고 부른다.

11. 콜백 함수에 대해 설명하라*

어떤 특정 함수가 실행을 마친 후에 실행되는 함수

함수는 인자로써 함수를 받을 수 있고, 다른 함수를 리턴할 수 있다. 이러한 특징을 가지는 함수를 고차함수(higher-order functions) 라고 한다.

인자로 전달되는 함수를 콜백 함수라고 부른다.

사용되는 이유: 비동기식 처리를 위해서

바로 처리될 수 없는 함수 (예: setTimeout)의 요청이 있다면 자바스크립트는 비동기 처리를 기다려주지 않는다.

순서를 보장하기 위해 함수의 인자로 콜백함수를 넣고, 비동기 처리가 끝나는 시점에 콜백함수를 실행시켜주는 것.

정리하면 콜백함수는 다른 함수의 실행이 끝날 때까지 특정 코드가 실행되지 않게 기다려주는 방법이다.

12. JavaScript의 언어적인 특징을 이야기 해봐라

  1. 자바스크립트는 객체 기반의 스크립트 언어
  2. 자바스크립트는 동적이며, 타입을 명시할 필요가 없는 인터프리터 언어
  3. 자바스크립트는 객체 지향형 프로그래밍과 함수형 프로그래밍을 모두 표현 가능

C언어와 같은 언어는 소스 파일을 작성한 후, 해당 파일을 컴파일(compile)하여 사용자가 실행할 수 있는 실행 파일(.exe)로 만들어 사용한다.
하지만 인터프리터 언어는 이러한 컴파일 작업을 거치지 않고, 소스 코드를 바로 실행할 수 있는 언어를 의미한다.
자바스크립트는 웹 브라우저에 포함된 자바스크립트 인터프리터가 소스 코드를 직접 해석하여 바로 실행해 준다.

13. ES6 특징들을 이야기 해봐라

자바스크립트 ES6 특징들
여기에 자세하게 나와있다. 참고해보자^^

14. async/await에 대해 설명하라

Promise를 다루기 위해 생긴 문법

async:

  • Promise를 반환하는 함수
  • 만일함수가 실제로 promise가 아닌 값을 반환해도, "async" 키워드로 정의된 함수는 자바스크립트에서 자동으로 그 값을 resolve promise로 변환해 반환한다
async function f() {
  return 1;
}

f().then(alert); // 1

await:

  • 키워드 await은 자바스크립트가 promise가 작업 이후 결과 값을 리턴할 때까지 잠시 기다리게 만든다.
  • await 연산자는 async function 내부에서만 사용할 수 있다
async function f() {
  
  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("done!"), 1000);
  });
  
  let result = await promise; // promise가 resolve될 때까지 기다립니다 (*)
  
  alert(result); // 끝입니다!
}

f();

15. Promise에 대해 설명하고 예시를 들어봐라

싱글쓰레드인 자바스크립트에서 비동기 처리를 위해서 콜백(callback)을 사용하기 때문에 콜백의 중첩으로 인한 복잡도가 증가, 에러/예외 처리의 어려움이 있다.
이 문제를 프로미스로 해결한다.

예외처리 실패 예시:

try {
  setTimeout(() => { throw 'Error!'; }, 1000);
} catch(e) {
  console.log('에러 캐치 불가능...');
  console.log(e);
}

try-catch에서 비동기 함수의 콜백메서드에서 에러를 만들지만 catch하지 못한다.
(setTimeout()함수의 콜백은 이벤트큐에 있다가 콜스택이 비어지면 실행되기 때문)

프로미스 생성, 실행:

//프로미스 생성
const promise1 = function (param) {
  return new Promise (function (resolve, reject) {
    if (param) {
      resolve ("합격");
    }
    else {
      reject ("불합격");
    }
  });
}

//프로미스 실행
promise1(true).then(function(result) {
  console.log(result); // 합격
}, function(err) {
  console.log(err); // 불합격
});

결국 비동기함수를 만들어서 사용해야할 때 프로미스 객체를 리턴하게 만들어서 사용하면 콜백 중첩을 방지할 수 있고 에러처리를 수월하게 할 수 있다!

16. var, let, const의 차이점

ES6부터 변수 선언에 let과 const가 추가 되면서 var 변수 선언을 권장하지 않는다

var와 let, const의 차이

var은 변수 재선언이 가능하다.

// 이미 만들어진 변수이름으로 재선언했는데 아무런 문제가 발생하지 않는다.
var a = 'test'
var a = 'test2'

이는 유연한 변수 선언으로 간단한 테스트에는 편리 할 수 있겠으나, 코드량이 많아 진다면 어디에서 어떻게 사용 될지도 파악하기 힘들뿐더러 값이 바뀔 우려가 있다.

letconst는 변수 재선언이 불가능 하다.

let과 const의 차이

둘의 차이점 여부는 immutable, 불변성 여부이다.

let변수에 재할당이 가능하지만, const는 변수 재선언, 재할당 모두 불가능하다.

// let
let a = 'test'
let a = 'test2' // Uncaught SyntaxError: Identifier 'a' has already been declared
a = 'test3'     // 가능

// const
const b = 'test'
const b = 'test2' // Uncaught SyntaxError: Identifier 'a' has already been declared
b = 'test3'    // Uncaught TypeError:Assignment to constant variable.

실행 컨텍스트 측면에서의 차이

호이스팅을 알아보자.

자바스크립트는 ES6에서 도입된 let, const를 포함하여 모든 선언(var, let, const, function, function*, class)을 호이스팅한다. 호이스팅(Hoisting)이란, var 선언문이나 function 선언문 등을 해당 스코프의 선두로 옮긴 것처럼 동작하는 특성을 말한다.

변수는 선언 단계 > 초기화 단계 > 할당 단계 에 걸쳐 생성되는데 var 으로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어진다. 따라서 변수 선언문 이전에 변수를 참조하여 undefined를 반환한다.

console.log(foo); // undefined

var foo;
console.log(foo); // undefined

foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1

let 로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다.

console.log(foo); // ReferenceError: foo is not defined

let foo; // 변수 선언문에서 초기화 단계가 실행된다.
console.log(foo); // undefined

foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1

var, let, const 차이점 Javascript Hoisting
자세한 내용은 여기에!

17. Event delegation (이벤트 위임)과 Event bubbling (이벤트 버블링)에 대해 설명하라*

Event delegation

이벤트 위임(Event Delegation)은 다수의 자식 요소에 각각 이벤트 핸들러를 바인딩하는 대신 하나의 부모 요소에 이벤트 핸들러를 바인딩하는 방법이다.

DOM 트리에 새로운 요소(예: li)를 추가하더라도 이벤트 처리는 부모 요소(예: ul)에 위임 되기 때문에 새로운 요소에 이벤트를 핸들러를 다시 바인딩할 필요가 없다.

이는 이벤트가 이벤트 흐름에 의해 이벤트를 발생시킨 요소의 부모 요소에도 영향(버블링)을 미치기 때문에 가능한 것이다.

Event bubbling

계층적 구조에 포함되어 있는 HTML 요소에 이벤트가 발생할 경우 연쇄적 반응이 일어난다. 즉, 이벤트가 전파(Event Propagation)되는데 전파 방향에 따라 버블링(Event Bubbling)캡처링(Event Capturing)으로 구분할 수 있다.

자식 요소에서 발생한 이벤트가 부모 요소로 전파되는 것을 버블링이라 한다.

자바스크립트 이벤트
이벤트의 자세한 내용은 여기에...

18. null과 undefined 그리고 undeclared의 차이점은 무엇인가?

16번 문제에서 변수는 선언 단계 > 초기화 단계 > 할당 단계를 걸쳐 생성 된다고 언급했다.이 세가지의 차이점은 여기서 발생된다.

undeclared: 선언 단계가 이루어지지 않은 상태다.

use strict 명령어를 통해 엄격모드로 진입해야 만날 수 있다. 엄격모드가 아닌 자바스크립트에서 선언되지 않은 변수에 값을 할당하면 자동으로 global 변수로 취급되기 때문이다.

undefined: 선언은 되었으나 초기화 단계가 이루어지지 않은 상태다.

let foo;
console.log(foo); //undefined

null: 선언 되었고 초기화 하였으나, 빈 값을 원할 떄 null을 할당하여 사용한다.

여기서 주의해야 할 점은 == 연산자를 사용하여 nullundefined를 비교하면 자동형변환이 이루어지고, 둘 다 빈 값이기 때문에 true를 반환한다. 따라서 값과 자료형 둘다 비교하는 === 연산자를 써야 한다.

let foo; // undefined
let boo = null; // null

console.log(foo == boo); // true
console.log(foo === boo); // false

19. 다음 코드의 차이점은 무엇인가?

function Person() {}

var person = Person()

var person = new Person()
  1. 함수 선언문
    이 경우 함수는 호이스팅 되어 해당 스코프의 최상단에 선언한 것 과 동일하게 작동한다.

  2. 함수 표현식
    이 경우 함수 선언문과 달리 호이스팅 되지 않는다.

  3. new 생성자로 함수 호출
    함수를 호출할 때 new를 붙이면 새로운 객체를 만든 후에 이를 리턴한다.

20. ES6 에서 화살표 함수를 언제 쓰나? 왜 쓰이나?

화살표 함수는 익명 함수로만 사용할 수 있다. 따라서 화살표 함수를 호출하기 위해서는 함수 표현식을 사용한다. 또는 콜백 함수로 사용할 수 있다. 이 경우 일반적인 함수 표현식보다 표현이 간결하다.
화살표 함수를 사용해선 안되는 경우


프론트엔드 인터뷰 핸드북 여기에 프론트엔드에 대한 좋은 인터뷰 문제가 있다. 꼭 읽어 보도록 하자!

Cross-Origin Resource Sharing (CORS)

시간이 부족함으로...

추가) 함수 표현식 vs 함수 선언식

링크

추가) 이벤트 전파 버블링 막기

링크

profile
딩코딩코딩

1개의 댓글

comment-user-thumbnail
2021년 8월 9일

8번에서 전역객체와 window(전역)을 다르게 표기한 이유가 있나요?

답글 달기