Arrayでは、lengthの値を調べることによって空かどうかを判定することができますが、今回はObject(連想配列)が空かどうかを判定する方法を探ってみます。
空かどうかの判定方法
Object.keys(obj).lengthを使う
おそらく、最もポピュラーな方法が、Objectのkeys配列を取得することによって判定する方法です。
function isEmpty(obj){
return !Object.keys(obj).length;
}
console.log(isEmpty({})); // -> true
console.log(isEmpty({"a":"a"})); // -> false
for~inを使う
上述した、Object.keys().lengthを使う方法は、Chromeのバージョンによっては極端に速度が劣化(1.5倍程度)します。
現行のものは既に修正されているようですが、古いバージョンに対応しなければならなくなったときは以下を使ってください。
function isEmpty(obj){
for(let i in obj){
return false;
}
return true;
}
console.log(isEmpty({})); // -> true
console.log(isEmpty({"a":"a"})); // -> false
おそらく、以前のChrome(50以前で確認)では、keysメソッドで毎回列挙する処理が走っていたものと思われます。もしかすると他のブラウザでも速度劣化が見られるかもしれません。
(おまけ)無理矢理やってみる
こんなこともできますね。
function isEmpty(obj){
return JSON.stringify(obj) === "{}";
}
console.log(isEmpty({})); // -> true
console.log(isEmpty({"a":"a"})); // -> false
ただし低速です。
パフォーマンス計測
function isEmptyKeysLength(obj){
return !Object.keys(obj).length;
}
function isEmptyJSON(obj){
return JSON.stringify(obj) === "{}";
}
function isEmptyForIn(obj){
for(let i in obj){
return false;
}
return true;
}
function calcPerf(name, obj, fn){
console.time(name);
for(let i = 0; i < 100; i++){
fn(obj);
}
console.timeEnd(name);
}
var obj = {};
for(let i = 0; i < 100000; i++){
obj[String.fromCharCode(i)] = true;
}
calcPerf("keys.length", obj, isEmptyKeysLength);
calcPerf("forIn", obj, isEmptyForIn);
calcPerf("JSON.stringify", obj, isEmptyJSON);
keys().length | for~in | JSON.stringify |
---|---|---|
2399.83ms | 2441.23ms | 3595.88ms |
これを見ると、普通に使うにはkeysが最も簡潔かつ、適しているように見えますね。
まとめ
普通に判定するだけなら、Object.keys().lengthを使うのがよさそうです。見通しのよいコードを書くためにも、シンプルな判定方法を実装しましょう。