JS 기술면접 스터디 3주차: 호이스팅부터 이벤트 버블링까지

2019. 7. 21. 23:56프론트엔드 개발/JS & TS

기술면접 스터디 2주차에 이어 3주차를 진행하고 관련 내용을 정리합니다. 이전의 내용이 궁금하시다면 다음을 클릭해주세요.

전체 질문 리스트의 출처는 front-end-interview-handbook이며, 이 글은 스터디 내용을 복기하고 정리하는 글로 아주 상세한 기술내용을 담고 있진 않습니다. 관련해서는 이후에 따로 정리할 계획입니다.

 

3주차 질문은 호이스팅, JS 템플릿, attribute/property, load/DOMContentLoaded, 일치연산자, same-origin 정책, "use strict";, fizzbuzz 문제, 이벤트 버블링 등에 대한 내용입니다.

 

1. JavaScript 템플릿을 사용한 적이 있나요? 사용해봤다면, 어떤 라이브러리를 사용했나요?

JSX라고 하면 템플릿 언어가 떠오를 수도 있지만, JavaScript의 모든 기능이 포함되어 있습니다.
(React 공식 사이트 - 한국어)
JSX may remind you of a template language, but it comes with the full power of JavaScript.
(React 공식 사이트 - 영어)

템플릿은 HTML 조각을 동적으로 만들어 추가할 때 사용하는 것을 말합니다. ES6의 템플릿 문자열 리터럴, Angular 템플릿 등을 사용해 보았습니다. React에서 JSX도 사용해 보았으나 JSX는 템플릿이 아니라는 주장이 있고 React 공식 홈페이지에서도 JSX를 자바스크립트를 기반으로 하고 있다고 말할 뿐 템플릿 언어라고 하지 않습니다.

 

2. 호이스팅에 대해 설명하세요

변수 선언이 함수 또는 전역 코드의 상단에 이동하는 것과 같은 행동을 "호이스팅(hoisting)"이라고 불립니다.(MDN의 var)

호이스팅은 JavaScript에서 실행 콘텍스트(특히 생성 및 실행 단계)가 어떻게 동작하는가에 대한 일반적인 생각으로 여겨집니다. 일부에서 호이스팅을 변수 및 함수 선언이 물리적으로 작성한 코드의 상단으로 옮겨지는 것으로 가르치지만, 실제로는 그렇지 않습니다. 변수 및 함수 선언은 컴파일 단계에서 메모리에 저장되지만, 코드에서 입력한 위치와 정확히 일치한 곳에 있습니다. (MDN의 Hoisting)

호이스팅이란 var 선언문이나 function 선언문 등 모든 선언문이 해당 Scope의 선두로 옮겨진 것처럼 동작하는 특성을 말합니다. 하지만 MDN의 설명대로 실제로 그렇게 작동하는 것은 아닙니다. 자바스크립트는 모든 선언문(var, let, const, function, function*, class)이 선언되기 이전에 참조 가능합니다. 호이스팅은 크게 변수 호이스팅과 함수 호이스팅이 있습니다.


변수 호이스팅은 var로 정의한 변수는 전역에 선언, 초기화되는 현상을 뜻합니다. 정의된 변수의 스코프 내에 어디서든 변수를 참조할 수 있습니다. 함수 스코프를 따르기 때문에 함수 내의 변수가 아닌 모든 변수는 전역 스코프에 호이스팅되어 있습니다.

이런 메커니즘은 프로그래밍을 보다 쉽게 할 수 있도록 고안된 것으로 보이나 현실에선 복잡한 혼란을 주기 때문에 ES6에 도입된 let, const를 이용해 방지하는 것이 좋습니다. var와 달리 let, const는 블록스코프에서 호이스팅되고 선언은 되지만 초기화는 되지 않습니다. 이를 일시적 사각지대(TDZ)라고 하는데 이 변수는 참조할 수 없습니다.

console.log(a); // undefined, 선언과 초기화가 된 상태로 참조가 가능하되 할당되기 이전이므로 undefined가 뜹니다.
var a = 1;

console.log(b); // ReferenceError: Cannot access 'b' before initialization, 선언만 된 상태로 초기화가 되지 않아 참조가 불가하여 에러를 띄웁니다. 
const b = 2;

주의할 점은 let, const도 호이스팅이 된다는 것입니다.

let c = 1; // 전역 변수
{
  console.log(c); // ReferenceError: Cannot access 'foo' before initialization
  let c = 2; // 지역 변수
}

위 코드에서 console.log(c)가 전역변수 c의 값을 출력할 것으로 예상되지만 ReferenceError를 띄웁니다. 이것은 블록스코프 내에서 호이스팅이 발생하여 지역변수 c가 초기화 이전의 일시적 사각지대에 놓여 에러를 발생시켰다는 것을 보여줍니다.


함수 선언문으로 정의된 함수는 함수 선언, 초기화, 할당이 한번에 이루어지며, 이때문에 함수의 선언위치에 관계없이 어디에서든 참조가 가능합니다. 이를 함수 호이스팅이라고 합니다. 그러나 함수 표현식으로 정의된 함수는 변수 호이스팅이 적용됩니다.

 

3. event bubbling에 대해 설명하세요.

이벤트를 처리할 때 여러 요소에서 이벤트를 처리할 수 있는데 이때 이벤트가 일어난 요소에서 시작해 최상단 document까지 거슬러 올라가는 방법을 버블링이라고 합니다. 반면 가장 먼 조상에서부터 시작하는 방법은 캡쳐링이라고 합니다.

이벤트가 발생하면 캡쳐링과 버블링은 순차적으로 일어납니다.

 

4. "attribute"와 "property"의 차이점은 무엇인가요?*

attribute는 마크업에 적용되는 속성이고, property는 DOM에 적용된다. 크롬의 개발자 도구를 살펴보면 이를 구분해서 볼 수 있다.

 

5. 내장 JavaScript 객체를 확장하는 것이 좋은 생각이 아닌 이유는 무엇인가요?

JavaScript의 내장객체를 확장한다는 것은 prototype에 커스텀 함수나 변수를 추가, 할당한다는 것입니다. 그러나 외부 라이브러리 등 다른 곳에서 해당 객체를 사용하게 될 경우 혼란을 야기하고 원하는대로 동작하지 않을 수 있다.

하지만 기존의 내장객체의 메서드를 내가 원하는 기능으로 덮어씌워서 오히려 기능을 원하는 것만 남기고 나머지를 은폐할 수도 있습니다. 다만 외부 라이브러리를 쓸 경우에는 앞의 이유처럼 건드리지 않는 편이 좋을 것입니다.

6. document load 이벤트와 document DOMContentLoaded 이벤트의 차이점은 무엇인가요?

  • document.DOMContentLoaded(): DOMContentLoaded 이벤트는 최초 HTML 문서가 완전히 로드 및 파싱되었을때 발생되고, 스타일시트나 이미지 및 서브프레임 로드가 끝나기를 기다리지 않습니다.

  • document.load(): load 이벤트는 리소스와 그것에 의존하는 리소스들의 로딩이 완료되면 실행됩니다.

  • 참고자료

 

7. ==와 ===의 차이점은 무엇인가요?

  • ==: 값의 일치여부만을 확인, 가령 숫자 5와 문자 “5”는 다르지만 ==에선 같게 나타납니다.
  • ===: 값과 타입의 일치여부까지 확인하는 확실할 방법. 숫자 5와 문자 “5”는 타입에서 다르기 떄문에 ===에서 다르게 나타납니다.
    null == undefined // true
    null === undefined // false

 

8. JavaScript와 관련하여 same-origin 정책을 설명하세요.

same-origin 정책은 JavaScript가 도메인 경계를 넘어서 요청하는 것을 방지합니다. origin은 URI 체계, 호스트 이름, 포트 번호의 조합으로 정의됩니다. 이 정책은 한 페이지의 악의적인 스크립트가 해당 페이지의 DOM을 통해 다른 웹 페이지의 중요한 데이터에 접근하는 것을 방지합니다.

이것은 동시에 CORS 이슈를 발생시키는 원인이 됩니다. CORS를 서버에서 관련 설정해주면 다른 도메인의 클라이언트에서도 해당 서버에 접근 가능합니다.

 

9. 다음이 작동하게 만들어보세요.

duplicate([1, 2, 3, 4, 5]) // [1,2,3,4,5,1,2,3,4,5]
const duplicate = arr => [...arr, ...arr]
const duplicate = arr => arr.concat(arr);

 

10. 왜 Ternary expression이라고 부르고, "Ternary"라는 단어는 무엇을 나타내나요?

삼항연산자는 (조건) ? {참이면 실행할 문} : {거짓이면 실행할 문} 로 표현합니다. Ternary는 "셋으로 이루어진" 이라는 뜻입니다.

 

11. "use strict"; 이 무엇인가요? 사용시 장단점이 무엇인가요?

"use strict";는 암시적 전역 변수를 허용하지 않도록 코드 최상단에 씁니다.

"use strict";
i=1; // (x)
var i=1; // (o)

전역에서 this는 undefined이 됩니다.
하지만 엄격모드는 전역에 선언할 경우 모든 스크립트에 적용되므로 필요한 부분에만 함수로 감싸 적용하는게 좋습니다. 즉, 즉시실행함수안에 작성해야 한다는 뜻입니다.

  • 장점
    • 실수로 전역변수를 만드는 것이 불가능합니다.
    • 암묵적으로 실패한 예외를 throw하지 못하는 할당을 만듭니다.
    • 삭제할 수 없는 속성을 삭제하려고 시도합니다. (시도 효과가 없을 때까지)
    • 함수의 매개변수 이름은 고유해야합니다.
    • this는 전역 컨텍스트에서 undefined입니다.
    • 예외를 발생시키는 몇 가지 일반적인 코딩을 잡아냅니다.
    • 헷갈리거나 잘 모르는 기능을 사용할 수 없게 합니다.
  • 단점
    • 일부 개발자는 익숙하지 않은 기능이 많습니다.
    • function.caller와 function.arguments에 더 이상 접근할 수 없습니다.
    • 서로 다른 엄격한 모드로 작성된 스크립트를 병합하면 문제가 발생할 수 있습니다.
  • 참고자료 

 

12. 100까지 증가하면서 3의 배수에는 fizz를 출력하고, 5의 배수에는 buzz를 출력하고, 3과 5의 배수에는 fizzbuzz를 출력하는 for loop를 만드세요.

const fizzBuzz=()=>{
    let i;
    for (i=1;i<100+1;i++){
        if (i%3===0 && i%5===0) console.log(i, ‘fizzbuzz')
        else if(i%3===0) console.log(i, ‘fizz')
        else if (i%5===0) console.log(i, ‘buzz')
    }
}

 

 

JS 기술면접 스터디 2주차: 호스트 객체부터 Ajax까지

기술면접 스터디 1주차에 이어 2주차를 진행하고 관련 내용을 정리합니다. 1주차 내용이 궁금하시다면 여기를 클릭해주세요. 전체 질문 리스트의 출처는 front-end-interview-handbook이며, 이 글은 스터디 내용을..

one-it.tistory.com

 

JS 기술면접 스터디 1주차: 이벤트 위임부터 코드구성까지

개발 프로젝트 동아리 활동 중 JS기술 면접을 대비하고 싶은 사람들과 함께 지난 7주간 모여 스터디를 진행했습니다. 질문 리스트는 front-end-interview-handbook에서 가져왔으며 매주 모여 일정 분량의 질문에..

one-it.tistory.com