かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

JavaScript 空オブジェクト {} かどうか判別したい。

空オブジェクト {} は 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

undefinedtypeof undefined"undefined" になるのでコレで弾くことができる。
nulltypeof 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以降の最新ウェブ開発

初めてのJavaScript 第3版 ―ES2015以降の最新ウェブ開発

  • 作者:Ethan Brown
  • 発売日: 2017/01/20
  • メディア: 単行本(ソフトカバー)

アイカツ!成分が最近足りてなくて元気が出ない…