연습장

13. Type Checking 타입 체크 본문

JavaScript

13. Type Checking 타입 체크

js0616 2024. 7. 17. 04:32

https://poiemaweb.com/js-type-check

 

Type Checking | PoiemaWeb

자바스크립트는 동적 타입(dynamic typed) 언어이므로 변수에 어떤 값이 할당될 지 예측하기 어렵다. 아래 코드를 살펴보자.

poiemaweb.com

 

 

 

자바스크립트는 동적 타입(dynamic typed) 언어이므로 변수에 어떤 값이 할당될 지 예측하기 어렵다. 

function sum(a, b) {
    return a + b;
  }
 
  sum('x', 'y'); // 'xy'

 

숫자가 아닌 문자가 들어오더라도 에러없이 처리가 되어버린다. 

 


 

1. typeof
타입 연산자(Type Operator) typeof는 피연산자의 데이터 타입을 문자열로 반환한다.

 

typeof '';              // string
typeof 1;               // number
typeof NaN;             // number
typeof true;            // boolean
typeof [];              // object
typeof {};              // object
typeof new String();    // object
typeof new Date();      // object
typeof /test/gi;        // object
typeof function () {};  // function
typeof undefined;       // undefined
typeof null;            // object (설계적 결함)
typeof undeclared;      // undefined (설계적 결함)

 

typeof는 null을 제외한 원시 타입을 체크하는 데는 문제가 없지만 객체의 종류까지 구분하기 어렵다. 

 


 

2. Object.prototype.toString
Object.prototype.toString 메소드는 객체를 나타내는 문자열을 반환한다.

Function.prototype.call 메소드를 사용하면 모든 타입의 값의 타입을 알아낼 수 있다.

 

Object.prototype.toString.call('');             // [object String]
Object.prototype.toString.call(new String());   // [object String]
Object.prototype.toString.call(1);              // [object Number]
Object.prototype.toString.call(new Number());   // [object Number]
Object.prototype.toString.call(NaN);            // [object Number]
Object.prototype.toString.call(Infinity);       // [object Number]
Object.prototype.toString.call(true);           // [object Boolean]
Object.prototype.toString.call(undefined);      // [object Undefined]
Object.prototype.toString.call();               // [object Undefined]
Object.prototype.toString.call(null);           // [object Null]
Object.prototype.toString.call([]);             // [object Array]
Object.prototype.toString.call({});             // [object Object]
Object.prototype.toString.call(new Date());     // [object Date]
Object.prototype.toString.call(Math);           // [object Math]
Object.prototype.toString.call(/test/i);        // [object RegExp]
Object.prototype.toString.call(function () {}); // [object Function]
Object.prototype.toString.call(document);       // [object HTMLDocument]
Object.prototype.toString.call(argument);       // [object Arguments]
Object.prototype.toString.call(undeclared);     // ReferenceError

 

이를 활용하여 타입을 구분하는 함수를 만든다. 

function getType(target) {
    return Object.prototype.toString.call(target).slice(8, -1);
}

getType('');         // String
getType(1);          // Number
getType(true);       // Boolean
getType(undefined);  // Undefined
getType(null);       // Null
getType({});         // Object
getType([]);         // Array
getType(/test/i);    // RegExp
getType(Math);       // Math
getType(new Date()); // Date
getType(function () {}); // Function

 

function sum(a, b) {
    // a와 b가 number 타입인지 체크
    if (getType(a) !== 'Number' || getType(b) !== 'Number') {
      throw new TypeError('파라미터에 number 타입이 아닌 값이 할당되었습니다.');
    }
    return a + b;
  }
 
  console.log(sum(10, 20));   // 30
  console.log(sum('10', 20)); // TypeError

 

Object.prototype.toString를 사용하여 객체의 종류(일반 객체, 배열, Date, RegExp, Function, DOM 요소 등)까지 식별할 수 있는 타입 체크 기능을 작성하였다.

 


 

3. instanceof
객체가 어떤 클래스(또는 생성자 함수)의 인스턴스인지를 확인하는 데 사용됩니다

 
 object instanceof constructor

 

여기서 object는 검사할 객체이고, constructor는 객체가 인스턴스인지 확인하려는 클래스(또는 생성자 함수)입니다.

 

class Animal {
    constructor(name) {
      this.name = name;
    }
  }
 
  class Dog extends Animal {
    constructor(name, breed) {
      super(name);
      this.breed = breed;
    }
  }
 
  let dog = new Dog('Buddy', 'Golden Retriever');
 
  console.log(dog instanceof Dog);    // true
  console.log(dog instanceof Animal); // true, because Dog extends Animal
  console.log(dog instanceof Object); // true, because all objects in JavaScript inherit from Object
 

 

 

 

이를 이용해 css 함수에 타입 체크 기능을 추가해 보자. ..?

 

<!DOCTYPE html>
<html>
<body>
  <p>Hello</p>
  <p>Hello</p>
  <p>Hello</p>
  <p>Hello</p>
  <script>
    function getType(target) {
      return Object.prototype.toString.call(target).slice(8, -1);
    }

    function isString(target) {
      return getType(target) === 'String';
    }

    function isElement(target) {
      return !!(target && target instanceof HTMLElement);
      // 또는 `nodeType`을 사용할 수도 있다.
      // return !!(target && target.nodeType === 1);
    }

    // HTMLElement를 상속받은 모든 DOM 요소에 css 프로퍼티를 추가하고 값을 할당한다.
    function css(elem, prop, val) {
      // type checking
      if (!(isElement(elem) && isString(prop) && isString(val))) {
        throw new TypeError('매개변수의 타입이 맞지 않습니다.');
      }
      elem.style[prop] = val;
    }

    css(document.querySelector('p'), 'color', 'red');
    css(document.querySelector('div'), 'color', 'red');
    // TypeError: 매개변수의 타입이 맞지 않습니다.
  </script>
</body>
</html>

 


 

4. 유사 배열 객체

 

배열인지 체크하기 위해서는 Array.isArray 메소드를 사용한다.

console.log(Array.isArray([]));    // true
console.log(Array.isArray({}));    // false
console.log(Array.isArray('123')); // false

 

 

유사 배열 객체 (Array-like Object)는 JavaScript에서 배열처럼 동작하는 객체를 말합니다. 이 객체들은 배열과 비슷하게 인덱스(index)를 사용하여 요소에 접근할 수 있지만, 배열의 내장 메서드(예: push, pop, forEach 등)를 직접 사용할 수는 없습니다. 

  • length 프로퍼티를 갖는 객체로 문자열
  • arguments
  • HTMLCollection
  • NodeList 등

유사 배열 객체는 length 프로퍼티가 있으므로 순회할 수 있으며 call, apply 함수를 사용하여 배열의 메소드를 사용할 수도 있다.  length 프로퍼티의 값을 확인하여 유사배열인지 체크 할 수 있다. 

 

<!DOCTYPE html>
<html>
<body>
  <ul>
    <li></li>
    <li></li>
    <li></li>
  </ul>
  <script>
    console.log(undefined == null)
    const isArrayLike = function (collection) {
      // 배열 인덱스: 32bit 정수(2의 32제곱 - 1)
      // 유사 배열 인덱스: 자바스크립트로 표현할 수 있는 양의 정수(2의 53제곱 - 1)
      const MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
      // 빈문자열은 유사배열이다. undefined == null => true
      const length = collection == null ? undefined : collection.length;
      return typeof length === 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
    };

    // true
    console.log(isArrayLike([]));
    console.log(isArrayLike('abc'));
    console.log(isArrayLike(''));
    console.log(isArrayLike(document.querySelectorAll('li')));
    console.log(isArrayLike(document.getElementsByName('li')));
    console.log(isArrayLike({ length: 0 }));
    (function () {
      console.log(isArrayLike(arguments));
    }());

    // false
    console.log(isArrayLike(123));
    console.log(isArrayLike(document.querySelector('li')));
    console.log(isArrayLike({ foo: 1 }));
    console.log(isArrayLike());
    console.log(isArrayLike(null));
  </script>
</body>
</html>

 

 

 

유사 배열 객체를 배열로 변환하려면 Array.from()이나 스프레드 연산자(...)를 사용하여 변환할 수 있습니다.

이렇게 하면 배열 메서드를 사용할 수 있게 됩니다.

 

function example() {
    console.log(arguments instanceof Array); // false, arguments는 유사 배열 객체이다.
 
    // 유사 배열 객체 arguments를 배열로 변환
    let argsArray = Array.from(arguments);
    console.log(argsArray instanceof Array); // true, 이제 배열이다.
 
    argsArray.push('new element'); // 배열 메서드 사용 가능
    console.log(argsArray); // 배열의 요소 출력
  }
 
  example('arg1', 'arg2', 'arg3');
 

 


 

typeof 의 특징?

 

object 를 구분하는 방법은?

 

instanceof 란?

 

유사 배열 객체 란? 

 

 

 

 

https://chatgpt.com/

'JavaScript' 카테고리의 다른 글

15. Scope 스코프  (0) 2024.07.18
14. Prototype 프로토타입  (0) 2024.07.17
12. Function 함수  (0) 2024.07.16
11. 객체와 변경불가성(Immutability)  (0) 2024.07.09
10. Object 객체  (0) 2024.07.09