空オブジェクト {} は true になるので空オブジェクトで場合分けしたい判別方法のメモ
Boolean({}); // => true
Object.keys().length と constructor で判定する
const isEmptyObject = (val) => { return val.constructor === Object && Object.keys(val).length === 0; }
空文字列 "", 空配列 [], 数値, Boolean, new Date() や function, Symbol , RegExp, class などは Object.keys() が空配列になるので、object.constructor === Object で弾く必要がある。
Object.keys(""); // => [] ("").constructor; // => String Object.keys([]); // => [] ([]).constructor; // => Array Object.keys(0); // => [] (0).constructor; // => Number Object.keys(-1.1); // => [] (1.1).constructor; // => Number Object.keys(NaN); // => [] (NaN).constructor; // => Number Object.keys(true); // => [] (true).constructor; // => Boolean Object.keys(false); // => [] (false).constructor; // => Boolean Object.keys(function() {}); // => [] (function() {}).constructor; // => Function Object.keys(new Date()); // => [] (new Date()).constructor; //=> Date Object.keys(Symbol()); // => [] (Symbol()).constructor; // => Symbol Object.keys(/\w/); // => [] (/\w/).constructor; // => RegExp class Foo(); Object.keys(new Foo()); // => [] (new Foo()).constructor; // => Foo
null, undefined でエラーになってしまうのを避ける
null, undefined は Object を継承していないので Object.keys() はTypeError になり constructor プロパティも持っていないのでエラーになってしまいます。
Object.keys(null); // TypeError: Cannot convert undefined or null to object (null).constructor; // TypeError: Cannot read property 'constructor' of null Object.keys(undefined) // TypeError: Cannot convert undefined or null to object (undefined).constructor // TypeError: Cannot read property 'constructor' of undefined
undefined は typeof undefined が "undefined" になるのでコレで弾くことができる。
null は typeof null が "object" になってしまうのでチョット厄介。素直に !== null とするのが良さそう。
後はエラーが発生するものを先に弾くように条件を追加すればOK。
const isEmptyObject = (val) => { return ( val !== null && typeof val === 'object' && val.constructor === Object && Object.keys(val).length === 0 ); };
TEST
isEmptyObject({}) // true isEmptyObject([]) // false isEmptyObject("") // false isEmptyObject(null) // false isEmptyObject(undefined) // false isEmptyObject(true) // false isEmptyObject(false) // false isEmptyObject(NaN) // false isEmptyObject(Infinity) //false isEmptyObject(0) // false isEmptyObject(-1) // false isEmptyObject(function() {}) / /false isEmptyObject(new Date()) // false isEmptyObject(Symbol()) // false isEmptyObject(/\w/) //false class Foo {} isEmptyObject(new Foo()) // false
できた🤟
まとめ
hasOwnProperty の事を考えると不十分な可能性がありますが、まぁだいたいこんな感じで判定できそうです。
TypeScript で判定する値の型がわかってるなら obj.constructor === Object && Object.keys(obj).length === 0; で十分なんじゃないかなー
hasOwnProperty もチェックできるパッケージ作りました
おわり
[参考]

初めてのJavaScript 第3版 ―ES2015以降の最新ウェブ開発
- 作者:Ethan Brown
- 発売日: 2017/01/20
- メディア: 単行本(ソフトカバー)

アイカツ! キラキラ★シールブック アニメ (まるごとシールブックDX)
- 発売日: 2014/03/27
- メディア: 文庫