やりたいこと
JavaScriptでObject
型のインスタンスなのかどうかを判定したい。
質問
function isObject(value) { return value !== null && typeof value !== 'undefined' && typeof value === 'object' && !Array.isArray(value); } console.log(isObject({}) // true console.log(isObject([]) //false console.log(isObject(null)) //false console.log(isObject(undefined)) //false console.log(isObject(new Date())) //true console.log(isObject(new Map())) //true
こんな感じの関数を作ればObject
型のインスタンスかどうかを判定できるかなと思ったのですが、関数を適用する対象がMap型のインスタンスやDate型のインスタンス等の場合、これでは上手く判定出来ませんでした。
なので、constructor.name
やtoString()
の値を比較してあげれば良いのかなと思い、
得られる値を確認するため、以下のようなデバッグコードを書いて実行してみました。
function debug(value) { console.log('value: ', value); value != null && console.log('constructor.name: ', value.constructor.name); console.log('toString: ', Object.prototype.toString.call(value)); console.log('=================='); } debug({}); debug(new Proxy({}, {})); debug(function(){}); debug(new Proxy(function(){}, {})); debug([]); debug(new Proxy([], {})); debug(new Map()); debug(new Proxy(new Map(), {})); debug(new WeakMap()); debug(new Proxy(new WeakMap(), {})); debug(new Set()); debug(new Proxy(new Set(), {})); debug(new WeakSet()); debug(new Proxy(new WeakSet(), {})); debug(Symbol('symbol')); debug(null); debug(undefined); debug((function(){ return arguments; })()); debug(new Date());
ログ
value: {} constructor.name: Object toString: [object Object] ================== value: Proxy {} constructor.name: Object toString: [object Object] ================== value: ƒ (){} constructor.name: Function toString: [object Function] ================== value: ƒ anonymous() constructor.name: Function toString: [object Function] ================== value: [] constructor.name: Array toString: [object Array] ================== value: Proxy {length: 0} constructor.name: Array toString: [object Array] ================== value: Map(0) {} constructor.name: Map toString: [object Map] ================== value: Proxy {} constructor.name: Map toString: [object Map] ================== value: WeakMap {} constructor.name: WeakMap toString: [object WeakMap] ================== value: Proxy {} constructor.name: WeakMap toString: [object WeakMap] ================== value: Set(0) {} constructor.name: Set toString: [object Set] ================== value: Proxy {} constructor.name: Set toString: [object Set] ================== value: WeakSet {} constructor.name: WeakSet toString: [object WeakSet] ================== value: Proxy {} constructor.name: WeakSet toString: [object WeakSet] ================== value: Symbol(symbol) constructor.name: Symbol toString: [object Symbol] ================== value: null toString: [object Null] ================== value: undefined toString: [object Undefined] ================== value: Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ] constructor.name: Object toString: [object Arguments] ================== value: Wed May 09 2018 17:06:26 GMT+0900 (JST) constructor.name: Date toString: [object Date] ==================
実行結果を見る限りだと、constructor.name
よりはtoString()
の値の方が信頼出来そうに感じたのですが、
以下のようなコードでObject
型のインスタンスかどうかを判定するのは安全、かつ、確かでしょうか?
function isObject(value) { // return value !== null && typeof value !== 'undefined' && Object.prototype.toString.call(value) === '[object Object]'; // nullかundefinedのチェックも不要になったので消します return Object.prototype.toString.call(value) === '[object Object]'; }
注釈
尚、new Proxy({}, {})
とした場合も[object Object]
となりますが、これはisObject()
の結果がtrue
であって構いません。
回答2件
あなたの回答
tips
プレビュー