트랙
/
JavaScript
JavaScript
/
연습 문제
/
재활용 로봇
재활용 로봇

재활용 로봇

학습 연습 문제

소개

데이터의 타입이 무엇인지 아는 것은 코드가 오류 없이 매끄럽게 실행되는 데 자주 아주 중요해요.

Javascript에는 값이나 객체의 타입을 확인하는 여러 가지 방법이 있어요.

Note

Javascript의 타입 확인 방식은 다소 믿기 어려울 때가 있어요.

더 나은 타입 안전성과 더 강한 타입을 원한다면, JavaScript를 기반으로 하면서도 정적 타입 언어의 타입 문법을 갖춘 TypeScript를 사용하는 게 좋아요.

typeof 연산자

typeof 연산자는 피연산자의 타입을 반환해요. 결과는 "null"을 제외하면 원시 데이터 타입 중 하나의 이름과 일치하는 문자열이에요. "function"이나 "object"일 수도 있어요.

typeof undefined;
// => "undefined"

typeof true;
// => "boolean"

typeof 42;
// => "number"

typeof 'Hello, World!';
// => "string"

typeof function () {
  return 'Hello, World';
};
// => "function"

typeof [1, 2, 3, 4];
// => "object"

typeof { city: 'Stockholm', country: 'Sweden' };
// => "object"

[역사적인 이유][typeof null is "object"] 때문이에요.

instanceof 연산자

객체의 타입을 확인하려면 instanceof 연산자를 사용할 수 있어요. instanceof는 두 번째 피연산자가 첫 번째 피연산자의 프로토타입 체인에 포함되는지에 따라 boolean 값을 내놓아요. 다시 말해, instanceof는 첫 번째 피연산자가 두 번째 피연산자나 그 자식 클래스의 인스턴스인지 여부를 반환해요. instanceof는 객체에만 동작해요.

class Beverage {
  // ...
}

// The Coffee class is a child of the Beverage class.
class Coffee extends Beverage {
  // ...
}

const java = new Coffee();

java instanceof Coffee;
// => true

java instanceof Beverage;
// => true
Advanced

Array 클래스에는 인자가 배열인지 확인하는 Array.isArray()라는 메서드가 있어요.

웹페이지의 iframe처럼 다른 렐름에서 만들어진 배열에는 instanceof Array가 동작하지 않지만, Array.isArray()는 동작해요.

이는 렐름마다 Array 클래스의 생성자가 다르기 때문이에요. 각 iframe은 자기만의 렐름을 가지고, 그래서 프로토타입 체인의 함수도 달라져서 instanceof Array가 실패해요. Array.isArray()는 이를 무시할 수 있어서, 가능하면 항상 사용하는 게 좋아요.

또한 객체가 실제로는 Array가 아니고 프로토타입 체인에 Array가 있을 뿐인 경우의 오탐도 피할 수 있어요.

({ __proto__: Array.prototype }) instanceof Array
// => true

Array.isArray({ __proto__: Array.prototype })
// => false

in 연산자

in 연산자는 첫 번째 피연산자가 두 번째 피연산자의 속성인지를 반환해요. 속성에 값이 정의되어 있는지는 확인하지 않아요. 값이 undefined로 설정된 속성도 in은 여전히 찾아내요.

class Coffee {
  constructor() {
    this.temperature = 'hot';
    this.isDarkMatter = undefined;
  }

  coolDown() {
    this.temperature = 'warm';
  }
}

const espresso = new Coffee();

'temperature' in espresso;
// => true

'color' in espresso;
// => false

'isDarkMatter' in espresso;
// => true
Note

in은 상속된 속성과 메서드에도 true를 반환해요.

"coolDown" in espresso
// => true

"constructor" in espresso
// => true

이를 피하려면 대신 Object.hasOwn()을 사용해요

Object.hasOwn() 함수

Object.hasOwn() 메서드는 지정한 객체가 주어진 속성을 직접 소유하고 있는지(상속받은 것이나 메서드가 아닌지)를 반환해요.

class Coffee {
  constructor() {
    this.temperature = 'hot';
  }

  coolDown() {
    this.temperature = 'warm';
  }
}
const cappuccino = new Coffee();

Object.hasOwn(cappucino, 'temperature');
// => true

Object.hasOwn(cappucino, 'constructor');
// => false

Object.hasOwn(cappucino, 'coolDown');
// => false

지침

지침

재활용 센터에 취직했어요. 공간이 부족해서 모든 제품이 같은 컨베이어 벨트에 놓이는데, 이 때문에 서로 다른 재질이 섞여서 쓸 수 없게 되어 버렸어요. 이 문제를 해결하기 위해, 제품의 종류를 판별하는 함수를 만드는 일을 맡았어요.

1. 값이 불리언인지 확인하기

값이 불리언인지 확인하는 isBoolean 함수를 구현해요.

isBoolean(true);
// => true

isBoolean(null);
// => false

2. 값이 숫자인지 확인하기

값이 유한한 number 또는 bigint인지, 즉 NaN이나 Infinity가 아닌지 확인하는 isNumber 함수를 구현해요.

가끔 ID를 읽는 장치가 고장 나서 숫자가 아닌 값을 NaN(Not a Number)이나 Infinity로 읽어요. 함수는 이런 상황도 올바르게 처리할 수 있어야 해요.

isNumber(42);
// => true

isNumber('Hello, World!');
// => false

isNumber(42n);
// => true

isNumber(NaN);
// => false

3. 값이 객체인지 확인하기

값이 객체인지 확인하는 isObject 함수를 구현해요. 컨베이어에서 null은 아무것도 아니므로 객체로 취급하지 않아요.

isObject({ greeting: 'Hello' });
// => true

isObject(25n);
// => false

4. 문자열이 숫자인지 확인하기

값이 숫자로만 이루어져 있거나, 음수를 나타내는 마이너스 기호 뒤에 숫자가 오는 문자열인지 확인하는 isNumericString 함수를 구현해요. 정수만 고려해야 하며, 재활용 로봇의 이 검사에서는 소수를 숫자로 취급하지 않아요.

isNumericString(42);
// => false

isNumericString('42');
// => true

isNumericString('Hi!');
// => false

5. 객체가 전자 기기인지 확인하기

객체가 주어진 ElectronicDevice 클래스나 그 자식 클래스의 인스턴스인지 확인하는 isElectronic 함수를 구현해요.

class Duck {
  //...
}

class WashingMachine extends ElectronicDevice {
  //...
}

isElectronic(new Duck());
// => false

isElectronic(new WashingMachine());
// => true

6. 값이 비어 있지 않은 배열인지 확인하기

값이 비어 있지 않은 배열인지 확인하는 isNonEmptyArray 함수를 구현해요.

isNonEmptyArray([1, 2, 3]);
// => true

isNonEmptyArray([]);
// => false

7. 값이 빈 배열인지 확인하기

값이 빈 배열인지 확인하는 isEmptyArray 함수를 구현해요.

isEmptyArray([1, 2, 3]);
// => false

isEmptyArray([]);
// => true

8. 객체에 type 속성이나 메서드가 있는지 확인하기

객체에 type 속성이나 메서드가 있는지 확인하는 hasType 함수를 구현해요.

class Keyboard(){
  type(){
    // ...
  }
}
hasType({ type:"car", color:"red" })
// => true

hasType({ color:"green" })
// => false

hasType(new Keyboard())
// => true

9. 객체에 id 속성이나 메서드가 없으면 오류를 던지기

객체에 id 속성이 없으면 Error를 던지는 assertHasId 함수를 구현해요.

객체에 id 속성이 있으면 아무것도 반환하지 않아야 해요.

assertHasId({ id: 42, color: 'red' });
// => undefined

assertHasId({ color: 'green' });
// Error: "Object is missing the 'id' property"

10. 객체에 id 속성이 있는지 확인하기

객체에 id 속성이 있는지 확인하는 hasIdProperty 함수를 구현해요.

class SimpleData {
  constructor() {
    this.number = '42';
    this.id = 'BC269327FE1D9B95';
  }
}

class StealingData extends SimpleData {}

class MethodData {
  constructor() {
    this.number = '42';
    this._id = 'BC269327FE1D9B95';
  }

  get id() {
    return this._id;
  }
}

hasIdProperty(new SimpleData());
// => true

hasIdProperty(new MethodData());
// => false

hasIdProperty(new StealingData());
// => false

11. 객체에 정의된 type 속성이 있는지 확인하기

객체에 undefined가 아닌 type 속성이 있는지 확인하는 hasDefinedType 함수를 구현해요.

hasDefinedType({ type: undefined, color: 'red' });
// => false

hasDefinedType({ type: 'car', color: 'green' });
// => true
GitHub에서 편집 링크가 새 창이나 탭에서 열려요
JavaScript Exercism

재활용 로봇 문제를 시작해 볼 준비가 됐나요?

Exercism에 가입하고 JavaScript 트랙을 개념 37개연습 문제 159개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.