logo

70 자바스크립트 인터뷰 질문 - 4부(번역)

70 JavaScript Interview Questions

javascript, interview, translation


출처

70 JavaScript Interview Questions

시작하며

글이 긴 관계로 4부로 나눠서 진행하며 1부는 1-17번 질문, 2부는 18-36번, 3부는 37-54번, 4부는 55-70번 질문으로 구성되어 있다.

Hi Guys Good Day and a Happy New Year 🎆🎆🎆!

이 글은 긴 내용이므로 한두 시환간 동안 나와 함께하시길 바랍니다. 모든 질문에 대한 답변에는 질문 목록으로 돌아가는 화살표 ↑ 링크가 있어서 스크롤 하는 시간을 낭비하지 않아도 됩니다.

질문

55. 암묵적(Implicit)명시적(Explicit) 강제변환(Coercion)의 차이점은 무엇인가?

**암묵적 강제변환(Implicit Coercion)**는 프로그래머가 직접 또는 손으로 하지 않고도 값을 다른 타입으로 변환하는 방법입니다.

아래에 예제가 있다고 가정해봅시다.

console.log(1 + '6'); // string
console.log(false + true); // number
console.log(6 * '2'); // number

첫번째 console.log문은 16을 로그로 기록합니다. 다른 언어에서는 컴파일 타임 에러를 던집니다. 하지만 JavaScript에서 1은 문자열로 변환된 뒤 + 연산자와 연결됩니다. 우리는 아무것도하지 않았지만 JavaScript를 통해 자동으로 변환되었습니다.

두번째 console.log문은 1을 로그로 기록하는데 false0이 되고 true1이 되는 boolean값이라 결과가 1이 됩니다.

세번째 console.log문은 12를 로그로 기록하고 6 * 2를 곱하기 전에 '2'를 숫자로 변환하므로 결과는 12입니다.

JavaScript Coercion Rules

반면에 **명시적 강제변환(Explicit Coercion)**은 값을 프로그래머가 다른 타입으로 변환하는 명시적(직접) 실행 방법입니다.

console.log(1 + parseInt('6'));

이 예제에서 parseInt 함수를 사용하여 '6'number로 변환한 후 +연산자를 써서 16을 더합니다.

56. NaN이란 무엇인가? 값이 NaN인지 확인하는 방법은 무엇인가?

NaN“숫자가 아님” 이라는 뜻으로 number를 number가 아닌 값으로 변환이나 수행하는 작업을 통해 NaN 결과 값을 받는데 이러한 JavaScript의 값을 의미합니다.

let a;

console.log(parseInt('abc')); // NaN
console.log(parseInt(null)); // NaN
console.log(parseInt(undefined)); // NaN
console.log(parseInt(++a)); // NaN
console.log(parseInt({} * 10)); // NaN
console.log(parseInt('abc' - 2)); // NaN
console.log(parseInt(0 / 0)); // NaN
console.log(parseInt('10a' * 10)); // NaN

JavaScript는 값이 isNaN값인지 테스트하는 내장 메서드 isNaN이 있습니다. 그렇지만 이 함수에는 이상한 동작이 있습니다.

console.log(isNaN()); //logs true
console.log(isNaN(undefined)); //logs true
console.log(isNaN({})); //logs true
console.log(isNaN(String('a'))); //logs true
console.log(isNaN(() => { })); //logs true

전달하는 값이 NaN이 아니더라도 모든 console.log 문은 true를 리턴합니다.

ES6 또는 ECMAScript 2015에서 Number.isNaN 메서드를 사용하는 것을 권장합니다. 왜냐하면 실제로 이것은 정말 NaN인지 값을 확인합니다. 또는 JavaScript에서 NaN은 그 자체와 같지 않은 유일한 값이기 때문에 이 문제를 확인하는 helper 함수를 만들 수도 있습니다.

function checkIfNaN(value) {
  return value !== value;
}

57. 어떻게 값이 Array인지 확인하는가?

Array 글로벌 객체에서 사용 가능한 Array.isArray 메서드를 사용해서 값이 Array인지 확인할 수 있습니다. 이 메서드는 매개 변수가 Array 인 경우 true를, 그렇지 않으면 false를 리턴합니다.

console.log(Array.isArray(5));  //logs false
console.log(Array.isArray("")); //logs false
console.log(Array.isArray()); //logs false
console.log(Array.isArray(null)); //logs false
console.log(Array.isArray({ length: 5 })); //logs false

console.log(Array.isArray([])); //logs true

개발 환경이 이 메서드를 지원하지 않으면 polyfill 구현해서 사용할 수 있습니다.

function isArray(value){
  return Object.prototype.toString.call(value) === "[object Array]"
}

58. % 또는 모듈로 연산자를 사용하지 않고 number가 짝수인지 확인하는 방법은 무엇인가?

이 문제에 비트 AND & 연산자를 사용할 수 있습니다. &는 피연산자에서 작동하여 이진수(binary values)로 처리하고 AND 연산을 수행합니다.

function isEven(num) {
  if (num & 1) {
    return false;
  } else {
    return true;
  }
};

이진수에서 0000입니다. 이진수에서 1001입니다. 이진수에서 2010입니다. 이진수에서 3011입니다. 이진수에서 4100입니다. 이진수에서 5101입니다. 이진수에서 6110입니다. 이진수에서 7111입니다. 등등…

a b a & b
0 0 0
0 1 0
1 0 0
1 1 1

따라서 console.log를 확인하면 5 & 1 표현식은 1을 리턴합니다. 먼저, & 연산자는 두 숫자를 이진수로 변환합니다. 그래서 5101로, 1001로 바뀝니다.

그런 다음 비트 AND 연산자를 사용해서 모든 비트 (0과 1) 를 비교합니다. 101 & 001. 표에서 볼 수 있듯이 a AND b가 1인 경우 결과는 1일 것입니다.

101 & 001
101
001
001
  • 먼저 가장 왼쪽의 1 & 0을 비교하고 결과는 0이 됩니다.
  • 그 다음 중간 비트 0 & 0을 비교하고 결과는 0이 됩니다.
  • 그 다음 마지막 비트 1 & 1을 비교하고 결과는 1이 됩니다.
  • 그 다음 이진 결과 001은 10 진수로 변환되어 1이 됩니다.

우리가 console.log를 확인하면 4 & 1 표현식은 0을 리턴 할 것입니다. 4의 마지막 비트를 아는 것은 0이고 0 & 10이 됩니다. 이해하기 어려울때는 재귀 함수를 사용하여 이 문제를 해결할 수 있습니다.

function isEven(num) {
  if (num < 0 || num === 1) return false;
  if (num == 0) return true;
  return isEven(num - 2);
}

59. 객체에 특정 속성이 있는지는 어떻게 확안하는가?

속성이 객체에 존재하는지 확인하는 세 가지 방법이 있습니다.

첫번째로 in 연산자를 사용하는 것입니다. in 연산자를 사용하는 문법은 propertyname in object와 같습니다. 속성이 존재하면 true를, 그렇지 않으면 false를 리턴합니다.

const o = {
  "prop" : "bwahahah",
  "prop2" : "hweasa"
};

// true. "prop"속성이 "o"객체에 있음을 나타냄
console.log("prop" in o);

// false. "prop"속성이 "o"객체에 없음을 나타냄
console.log("prop1" in o);

두번째로, 객체에서 hasOwnProperty 메서드를 사용하는 것입니다. 이 방법은 JavaScript의 모든 객체에서 사용할 수 있습니다. 속성이 존재하면 true를, 그렇지 않으면 false를 리턴합니다.

// 첫 번째 예제의 o 객체를 사용합니다.
console.log(o.hasOwnProperty("prop2")); // true
console.log(o.hasOwnProperty("prop1")); // false

세번째로, 대괄호 표기법 obj["prop"]를 사용하는 것입니다. 속성이 존재하면 해당 속성의 값을 리턴하고 그렇지 않으면 undefined를 리턴합니다.

// 첫 번째 예제의 o 객체를 사용합니다.
console.log(o["prop"]); // "bwahahah"
console.log(o["prop1"]); // undefined

60. AJAX 란 무엇인가?

AJAX는 비동기 JavaScript 및 XML을 말합니다. 비동기식으로 데이터를 표시하는데 사용되는 관련 기술 그룹입니다. 이말은 즉, 웹 페이지를 다시 로드하지 않고도 서버로 데이터를 보내고 서버에서 데이터를 가져올 수 있다는 것입니다.

AJAX에 대한 기술 사용

  • HTML - 웹 페이지 구조
  • CSS - 웹 페이지 스타일
  • JavaScript - 웹 페이지의 동작 및 DOM 업데이트
  • XMLHttpRequest API - 서버에서 데이터를 보내고 되찾아오는데 사용
  • PHP, Python, Nodejs - 일부 서버 사이드 언어

61. JavaScript로 객체를 만드는 방법은 무엇인가?

객체 리터럴 사용

  const o = {
    name: "Mark",
    greeting() {
      return `Hi, I'm ${this.name}`;
    }
  };

  o.greeting(); // returns "Hi, I'm Mark"

Constructor 함수 사용

function Person(name) {
  this.name = name;
}

Person.prototype.greeting = function () {
  return `Hi, I'm ${this.name}`;
}

const mark = new Person("Mark");

mark.greeting(); // returns "Hi, I'm Mark"

Object.create 메서드 사용

const n = {
  greeting() {
    return `Hi, I'm ${this.name}`;
  }
};

// "o"의 프로토 타입을 "n"으로 설정
const o = Object.create(n);

o.name = "Mark";

console.log(o.greeting()); // logs "Hi, I'm Mark"

62. Object.sealObject.freeze 메서드의 차이점은 무엇인가?

두 메서드의 차이점은 Object.freeze를 객체에 사용할 때, 객체 속성은 불변이 됩니다. 즉, 해당되는 속성 값을 변경하거나 수정할 수 없습니다. 반면에 Object.seal 메서드에서 기존 속성을 변경할 수 있습니다.

63. 객체에서 in 연산자와 hasOwnProperty 메서드의 차이점은 무엇인가?

이 두 기능을 모두 알고 있으므로 객체에 속성이 있는지 확인하십시오. 이것은 true false를 리턴합니다. 두 기능의 차이점으로는 in 연산자는 현재 객체에서 속성을 못 찾을 경우 객체의 프로토 타입 체인을 검사합니다. 반면에 hasOwnProperty 메서드는 프로토 타입 체인을 무시하고 현재 객체에 속성이 존재하는지만 확인합니다.

// 이전 질문의 객체를 사용
console.log("prop" in o); // true
console.log("toString" in o); // true. 이 객체의 프로토 타입인 Object.prototype에서 toString 메서드를 사용할 수 있음

console.log(o.hasOwnProperty("prop")); // true
console.log(o.hasOwnProperty("toString")); // false. 객체의 프로토 타입을 확인하지 않음

64. JavasScript에서 어떻게 비동기 코드를 처리하는가?

65. 함수 표현식(function expression)과 함수 선언(function declaration)의 차이점은 무엇인가?

아래와 같은 예제가 있다고 가정해봅시다.

hoistedFunc();
notHoistedFunc();

function hoistedFunc(){
  console.log("I am hoisted");
}

var notHoistedFunc = function(){
  console.log("I will not be hoisted!");
}

notHoistedFunc 호출은 에러를 던지지만 hoistedFunc 호출은 그렇지 않습니다. hoistedFunc은 호이스팅되고 반면에 notHoistedFunc은 호이스팅 되지 않기 때문입니다. 호이스팅에 관한 질문

66. 함수는 몇 가지 방법으로 호출 할 수 있는가?

JavaScript에서 함수를 호출하는 방법에는 4가지가 있습니다. 호출은 this 또는 해당 함수의 “소유자” 객체 값을 결정합니다.

  • 함수로 호출 - 함수가 메서드, constructor 또는 apply, call 메서드와 함께 호출되지 않은 경우 함수로 호출됩니다. 이 함수의 “owner” 객체는 window 객체가 됩니다.
//Global 스코프
function add(a,b){
  console.log(this);
  return a + b;
}

add(1, 5); // 로그는 "window" 객체와 6을 리턴

const o = {
  method(callback){
    callback();
  }
}

o.method(function () {
  console.log(this); // 로그는 "window" 객체
});
  • 메서드로 호출 - 객체의 속성에 함수 값이 있으면 이를 메서드라고 합니다. 해당 메서드호출되면 this 값이 해당 객체가 됩니다.
const details = {
  name : "Marko",
  getName() {
    return this.name;
  }
}

details.getName(); // Marko 리턴
// "getName"메서드 내의 "this"값은 "details"객체
  • constructor로 호출 - 함수가 new 키워드로 호출된 경우 이를 함수 생성자(constructor)라고 합니다. 빈 객체가 만들어지고 this는 해당 객체를 가리킵니다.
function Employee(name, position, yearHired) {
  // 빈 객체를 만듭니다 {}
  // 그런 다음 빈 객체를 "this"키워드에 할당합니다.
  // this = {};
  this.name = name;
  this.position = position;
  this.yearHired = yearHired;
  // Employee.prototype에서 상속
  // 명시적인 return 문이 지정되지 않은 경우 "this"값을 암시적으로 리턴합니다.
};

const emp = new Employee("Marko Polo", "Software Developer", 2017);
  • applycall 메서드를 사용한 호출 - this 값이나 함수의 “owner”객체를 명시적으로 지정하려면 이런 메서드들을 사용할 수 있습니다. 이러한 방법은 모든 함수에 사용할 수 있습니다.
const obj1 = {
  result: 0
};

const obj2 = {
  result: 0
};

function reduceAdd() {
  let result = 0;
  for(let i = 0, len = arguments.length; i < len; i++) {
    result += arguments[i];
  }
  this.result = result;
}

reduceAdd.apply(obj1, [1, 2, 3, 4, 5]);  // "reduceAdd"함수 내의 "this"객체는 "obj1"
reduceAdd.call(obj2, 1, 2, 3, 4, 5);  // "reduceAdd"함수 내의 "this"객체는 "obj2"

67. Memoization란 무엇이며 용도는 무엇인가?

Memoization은 이전에 계산된 결과 또는 값을 기억할 수 있는 함수를 만드는 프로세스입니다. Memoization 함수를 사용하는 것은 같은 인수로 마지막 계산에서 이미 수행된 경우 해당 함수의 계산을 피하는 것입니다. 이렇게하면 시간이 절약되지만 이전 결과를 저장하기 위해 더 많은 메모리를 소비한다는 단점이 있습니다.

68. Memoization helper 함수를 구현하시오.

function memoize(fn) {
  const cache = {};
  return function (param) {
    if (cache[param]) {
      console.log('cached');
      return cache[param];
    } else {
      let result = fn(param);
      cache[param] = result;
      console.log(`not cached`);
      return result;
    }
  }
}

const toUpper = (str = "") => str.toUpperCase();

const toUpperMemoized = memoize(toUpper);

toUpperMemoized("abcdef");
toUpperMemoized("abcdef");

이 memoize helper 함수는 하나의 인수를 허용하는 함수에서만 작동합니다. 여러 인수를 허용하는 memoize helper 기능을 만들어야합니다.

const slice = Array.prototype.slice;
function memoize(fn) {
  const cache = {};
  return (...args) => {
    const params = slice.call(args);
    console.log(params);
    if (cache[params]) {
      console.log('cached');
      return cache[params];
    } else {
      let result = fn(...args);
      cache[params] = result;
      console.log(`not cached`);
      return result;
    }
  }
}
const makeFullName = (fName, lName) => `${fName} ${lName}`;
const reduceAdd = (numbers, startingValue = 0) => numbers.reduce((total, cur) => total + cur, startingValue);

const memoizedMakeFullName = memoize(makeFullName);
const memoizedReduceAdd = memoize(reduceAdd);

memoizedMakeFullName("Marko", "Polo");
memoizedMakeFullName("Marko", "Polo");

memoizedReduceAdd([1, 2, 3, 4, 5], 5);
memoizedReduceAdd([1, 2, 3, 4, 5], 5);

69. typeof null은 왜 객체를 리턴하며 어떻게 값이 null인지 확인하는가?

typeof null == 'object'는 항상 true를 리턴합니다. 왜냐하면 이것은 JavaScript가 탄생 한 이후로 null을 구현했기 때문입니다. typeof null == 'object'typeof null == 'null'로 변경하는 수정이 제안되었습니다. 그러나 더 많은 버그로 이어질 수 있기 때문에 거부되었습니다.

=== 또는 엄격한 항등 연산자를 사용하여 값이 null인지 확인할 수 있습니다.

  function isNull(value) {
    return value === null;
  }

70. new 키워드는 무엇을 하는가?

new 키워드는 constructor 함수와 함께 사용되어 JavaScript로 객체를 만듭니다.

아래에 예제 코드가 있다고 가정합시다.

function Employee(name, position, yearHired) {
  this.name = name;
  this.position = position;
  this.yearHired = yearHired;
};

const emp = new Employee("Marko Polo", "Software Developer", 2017);

new 키워드는 4개의 일을 합니다.

  • 빈 객체를 만듭니다.
  • 빈 객체를 this 값에 할당합니다.
  • 함수는 functionName.prototype에서 상속됩니다.
  • 명시적인 return 문이 사용되지 않으면 this를 리턴합니다.

위 코드에서, 먼저 빈 객체 {}를 만듭니다. 그런 다음 this값은 빈 객체 this = {}가 됩니다. 그리고 this 객체에 속성을 추가합니다. 명시적인 return 서술문이 없기 때문에 자동으로 this를 리턴합니다.

Thanks guys for reading this post.