HOWTO · JavaScript
JavaScriptでプロパティの存在を確認する方法
今日の記事では、JavaScript にプロパティが存在するかどうかを確認する方法を学習します。
このページの内容
JavaScriptオブジェクトにプロパティが存在するか確認するには、「存在する」の意味をタスクに合わせて判定方法を選びます。Object.prototype.hasOwnProperty() はオブジェクト自身に直接格納されたプロパティだけを調べます。in 演算子は、自身のプロパティに加えてプロトタイプチェーンから継承したプロパティも調べます。
JavaScriptでプロパティの存在を確認する
オブジェクト自身がキーを定義しているかを調べるには、Object.prototype.hasOwnProperty() を使います。このメソッドは値ではなくキーの有無に基づいて真偽値を返すため、値が null や undefined の自身のプロパティも存在すると判定されます。安全に呼び出すには Object.prototype.hasOwnProperty.call(object, key) と書きます。オブジェクト自身に hasOwnProperty というプロパティがある場合にも使えます。キーには文字列またはシンボルを指定できます。同じメソッドで、配列があるインデックスを自身のプロパティとして持つかどうかも調べられます。詳しくは MDN の hasOwnProperty() を参照してください。
プロパティの有無と値の判定は分けて考えましょう。プロパティの値が undefined でも、そのプロパティがオブジェクト自身にあれば、own-property チェックの結果は true です。値を比較する方法では別の問いに答えることになります。同様に、in はプロトタイプから継承したキーにも true を返すことがありますが、そのキーを読み取るだけでは、どこで定義されたかは分かりません。自身のキーが必要なのか、アクセス可能なキー全般が必要なのかに合わせて判定方法を選びます。
継承したプロパティも存在するとみなす場合は、key in object を使います。これはメソッド呼び出しではなく演算子式です。左辺にはプロパティキー、右辺にはオブジェクトを指定します。配列では、インデックスを調べる際に配列のプロトタイプチェーンも対象になります。詳しくは MDN の in 演算子 を参照してください。
次の自己完結した例を実行します。
const defaults = { theme: 'light' };
const settings = Object.create(defaults);
settings.language = 'en';
console.log(Object.prototype.hasOwnProperty.call(settings, 'language'));
console.log(Object.prototype.hasOwnProperty.call(settings, 'theme'));
console.log('theme' in settings);
console.log('timezone' in settings);
if (!Object.prototype.hasOwnProperty.call(settings, 'timezone')) {
settings.timezone = 'UTC';
}
console.log(settings.timezone);
true
false
true
false
UTC
ここでは、language は自身のプロパティで、theme は defaults から継承しています。own-property チェックでは両者を区別できますが、in ではどちらも存在すると判定されます。timezone がない場合の条件には否定を使っているため、オブジェクト自身にそのプロパティがまだ定義されていないときだけ追加します。継承したキーがある場合も追加を防ぐには、同じ考え方で !('key' in object) を使います。提示された実行結果は、この順に true、false、true、false、UTC と出力されます。