JavaScriptで型判定いろいろ

型の判定をするときに「typeof」とか「instanceof」とか「==」とかしょっちゅう忘れる。
あとDOM要素もwindowだったりHTMLElementParagraphElementとかいろいろあってややこしや。

この辺、jQueryのisArray()やisFunction()ではどうやってるんだろと見てみると、「Object.prototype.toString.call(v)」でやってた。
いろいろな型で試してみたところ、これで全部いけるじゃん!と分かったので、まとめたやつを作ってみた。

・type.js

/**
 * Decision type of variable.
 * @class Type
 * @static
 */
var Type = {
  isObject: function(v) {
    return (Object.prototype.toString.call(v) == "[object Object]");
  },
  isFunction: function(v) {
    return (Object.prototype.toString.call(v) == "[object Function]");
  },
  isArray: function(v) {
    return (Object.prototype.toString.call(v) == "[object Array]");
  },
  isBoolean: function(v) {
    return (Object.prototype.toString.call(v) === "[object Boolean]");
  },
  isString: function(v) {
    return (Object.prototype.toString.call(v) === "[object String]");
  },
  isNumber: function(v) {
    return (Object.prototype.toString.call(v) === "[object Number]");
  },
  isElement: function(v) {
    var check = false;
    switch(Object.prototype.toString.call(v)) {
      case "[object Object]":
        if (v.length) check = true;
        break;
      case "[object Window]":
      case "[object HTMLParagraphElement]":
        if (! Type.isUndefined(v) && ! Type.isNull(v)) check = true;
        break;
      default:
        break;
    }
    return check;
  },
  isElementCollection: function(v) {
    return (Object.prototype.toString.call(v) === "[object HTMLCollection]");
  },
  isNull: function(v) {
    return (v === null);
  },
  isUndefined: function(v) {
    return (v === 'undefined');
  },
  /**
   * @method getType
   * @param {Any} v The variable
   * @return {String} type of the variable
   */
  getType: function(v) {
    if (Type.isNull(v)) { return "null"; }
    if (Type.isUndefined(v)) { return "undefined"; }
    if (Type.isElement(v)) { return "HTMLElement"; }
    return Object.prototype.toString.call(v).split(" ")[1].replace("]", "");
  }
};

・test.js

$(function() {

  var str = "abc";
  console.log(Type.getType(str)); // String

  var num = 100;
  console.log(Type.getType(num)); // Number

  var arr = [];
  console.log(Type.getType(arr)); // Array

  var obj = {};
  console.log(Type.getType(obj)); // Object

  var func = function() {};
  console.log(Type.getType(func)); // Function

  var etc1 = {};
  console.log(Type.getType(etc1.hoge)); // undefined

  var etc2 = null;
  console.log(Type.getType(etc2)); // null

  var el1 = document.getElementById("test1");
  console.log(Type.getType(el1)); // HTMLElement

  var el2 = $("#test2");
  console.log(Type.getType(el2)); // HTMLElement

  var el3 = document.getElementById("test3");
  console.log(Type.getType(el3)); // null

  var els1 = document.getElementsByClassName("tests");
  console.log(Type.getType(els1)); // HTMLCollection

  var els2 = document.getElementsByTagName("p");
  console.log(Type.getType(els2)); // HTMLCollection

  var els3 = document.getElementsByClassName("testsss");
  console.log(Type.getType(els3)); // HTMLCollection
});

・test.html

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Type test</title>
    <script type="text/javascript" src="jquery-1.3.2.js"></script>
    <script type="text/javascript" src="type.js"></script>
    <script type="text/javascript" src="test.js"></script>
  </head>
  <body>
    <p id="test1" class="tests">Test用文字列</p>
    <p id="test2" class="tests">Test用文字列</p>
  </body>
</html>

jQueryオブジェクトもHTML要素とみなしてます。オブジェクトとみなしてもいいのだけど、結局DOMとして扱うし。
nullとundefinedはtoString()で[object Window]が返ってくるので最初に判定する必要があります。

JavaScriptの型判定は割とバグの原因になりやすいので、前回書いたチーム開発の統一すべき項目に入れてもいいかも。