個人的に JavaScript の要素は全部 Object で、型の概念は実質存在しないという認識。(Stringも "foo".length
とか使える訳だし)
ある程度は typeof()
で判別することができるけど、Ruby とかで Hash とか Python で DIctionary (辞書) とかと呼ばれるような {a: 1}
みたいなオブジェクトだけを判定したいと思ったのでやってみたメモ。
色々なオブジェクトの typeof()
// String 'String' // 'string' new String('Foo') // 'object' // Number 1 // 'number' -1 // 'number' 1.5 // 'number' -0.8 // 'number' NaN // 'number' // Boolean true // 'boolean' false // 'boolean' null // 'object' // undefined undefined // 'undefined' // Array [] // 'object' [1, 2] // 'object' // Object (hash) {} // 'object' {a: 1, b: 2} // 'object' // Function function() {} // 'function' // Date new Date() // 'object' // RegExp /\w+/ // 'object' new RegExp('\\w+') // 'object' // Symbol Symbol() // 'symbol' Symbol( {} ) // 'symbol' // Class class MyClass { constructor() {} }; new MyClass() // 'object'
殆どのオブジェクトはそれぞれの型が表示されるが、{}
なオブジェクト以外で typeof()
した時に object と判定されるのは次の通り
Array の判別
配列に関しては Array.isArray()
で判定が可能
// 以下の呼び出しはすべてtrueを返す Array.isArray([]); Array.isArray([1]); Array.isArray(new Array()); Array.isArray(new Array('a', 'b', 'c', 'd')); Array.isArray(new Array(3)); // あまり知られていないものの Array.prototype は配列 Array.isArray(Array.prototype); // 以下の呼び出しはすべて false を返す Array.isArray(); Array.isArray({}); Array.isArray(null); Array.isArray(undefined); Array.isArray(17); Array.isArray('Array'); Array.isArray(true); Array.isArray(false); Array.isArray({ __proto__: Array.prototype });
Array.isArray()
で配列を除いてもまだ{}
なオブジェクトと null
, new String()
, Date
, RegExp
, Class
を判別することはできない
Object.prototype.toString.call()
で型を
Every object has a
toString()
method that is automatically called when the object is to be represented as a text value or when an object is referred to in a manner in which a string is expected. By default, thetoString()
method is inherited by every object descended fromObject
. If this method is not overridden in a custom object,toString()
returns"[object type]"
, where type is the object type.
ref. Object.prototype.toString() - JavaScript | MDN
var o = new Object(); o.toString(); // returns [object Object]
toString()
can be used with every object and allows you to get its class. To use theObject.prototype.toString()
with every object, you need to callFunction.prototype.call()
orFunction.prototype.apply()
on it, passing the object you want to inspect as the first parameter calledthisArg
.
ref. Object.prototype.toString() - JavaScript | MDN
var toString = Object.prototype.toString; toString.call(new Date); // [object Date] toString.call(new String); // [object String] toString.call(Math); // [object Math] // Since JavaScript 1.8.5 toString.call(undefined); // [object Undefined] toString.call(null); // [object Null]
Object.toString()
は [object type]
を返し、あらゆるオブジェクトは Object
を継承しているので Object.prototype.toString()
を call()
や apply()
で this
になるオブジェクトを変更して呼び出せば引数で渡した this
の型を表示することができる。
null
, new String()
, Array
Date
, RegExp
, Class
の場合
typeof()
, Array.isArray()
で除外できなかった null
, new String()
, Date
, RegExp
, Class
と Array
でどうなるか試してみた
function showObjectType(val) { const type = Object.prototype.toString.call(val); console.log( type.slice(8, -1) ); } showObjectType( null ); // 'Null' showObjectType( new String('foo') ); // 'String' showObjectType( new Date() ); // 'Date' showObjectType( /\w+/ ); // 'RegExp' showObjectType( new RegExp('\\w+') ); // 'RegExp' showObjectType( new MyClass ); // 'Object' showObjectType( [] ); // 'Array'
Class インスタンス以外はそれぞれの型が表示されるのでこれで除外することができる。
Array.isArray()
は内部的にこんな感じで判定しているのかもしれない。
Object.prototype.constructor
で判定
All objects (with the exception of objects created with
Object.create(null)
) will have aconstructor
property. Objects created without the explicit use of a constructor function (i.e. the object and array literals) will have aconstructor
property that points to the Fundamental Object constructor type for that object.
ref. Object.prototype.constructor - JavaScript | MDN
var o = {}; o.constructor === Object; // true var o = new Object; o.constructor === Object; // true var a = []; a.constructor === Array; // true var a = new Array; a.constructor === Array; // true var n = new Number(3); n.constructor === Number; // true
new String()
, Array
Date
, RegExp
, Class
の場合
null.constructor
はエラーになるので、null
以外でテストしてみる
function getConstructor(val) { if( val === null ) return false; const type = val.constructor; return type; } getConstructor( new String('foo') ); // [Function: String] getConstructor( new Date() ); // [Function: Date] getConstructor( /\w+/ ); // [Function: RegExp] getConstructor( new RegExp('\\w+') ); // [Function: RegExp] getConstructor( new MyClass ); // [Function: MyClass] getConstructor( [] ); // [Function: Array]
constructor
プロパティの場合 Class インスタンスは元のクラスがコンストラクターとして返されるので {}
なオブジェクトと判別することができる
{}
なオブジェクトを判別する関数
次の条件を満たしていれば {}
なオブジェクトだと判断できそうです
typeof()
が"object"
null
でないconstructor
がObject
function isObject(val) { if( val !== null && typeof(val) === 'object' && val.constructor === Object ) { return true; } return false; }
👇 TEST
isObject( "String" ); // => false isObject( new String("Foo") ); // => false isObject( 1 ); // => false isObject( -1 ); // => false isObject( 1.5 ); // => false isObject( -0.8 ); // => false isObject( NaN ); // => false isObject( true ); // => false isObject( false ); // => false isObject( null ); // => false isObject( undefined ); // => false isObject( [] ); // => false isObject( [ 1, 2 ] ); // => false isObject( {} ); // => true isObject( { a: 1, b: 2 } ); // => true isObject( function() {} ); // => false isObject( new Date() ); // => false isObject( /\w+/ ); // => false isObject( new RegExp('\\w+') ); // => false isObject( Symbol() ); // => false isObject( Symbol({}) ); // => false isObject( new MyClass() ); // => false isObject( new Object() ); // => true
判別できる npm パッケージを公開しました
[参考]
- Array.isArray() - JavaScript | MDN
- javascript:変数(オブジェクト)の型を確認する方法
- Object.prototype.constructor - JavaScript | MDN
- 作者: ピョートル・フェリークス・グジバチ
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2018/03/10
- メディア: 単行本
- この商品を含むブログを見る
鋼鉄の体が欲しいゼ…
コトブキヤ 攻殻機動隊 STAND ALONE COMPLEX 多脚戦車「剣菱重工 HAW206」 試作車ver. 1/35スケール プラスチックモデル
- 出版社/メーカー: 壽屋(KOTOBUKIYA)
- 発売日: 2013/10/23
- メディア: おもちゃ&ホビー
- この商品を含むブログ (3件) を見る