JavaScript 開発では、オブジェクトにプロパティが存在するかどうかを判断する必要があることがよくあります。
JavaScript は比較的緩い言語であるため、より厳密なことを行うのは困難です。たとえば、JavaScript における「属性が存在するかどうか」の定義には、どのような場合に属性が存在し、どのような場合に存在しないとみなされるかという問題があります。正解も不正解もありませんが、状況や開発ニーズが異なれば、「存在」の意味も異なります。
ここではよく使われる5つの判断方法とその問題点についてお話します。
これが例です:
const obj1 = { name: 'Andy', age: 21 } const obj2 = { name: 'Alice' } console.log( obj1.age ? '存在' : '不存在' ); // 存在 console.log( obj2.age ? '存在' : '不存在' ); // 不存在
まずこの方法の欠点について話しましょう
次の場合:
const obj = { name: 'Baby', age: 0 } console.log( obj.age ? '存在' : '不存在' ); // 不存在
この場合、年齢は「存在する」はずですが、「存在しない」と判定されてしまいます。
では、この方法は使えないのでしょうか?
これはビジネスの開発ニーズによって異なります。
ビジネス開発要件で、この属性を 0、空の文字列、NaN、未定義などにすることができないことがわかっている場合でも、この判断は可能です。
より厳しい環境に置くと、この方法には欠陥が生じます。
まず例を挙げてみましょう:
const obj1 = { name: 'Andy', age: 21 } const obj2 = { name: 'Alice' } console.log( obj1?.age !== undefined ? '存在' : '不存在' ); // 存在 console.log( obj2?.age !== undefined ? '存在' : '不存在' ); // 不存在
この比較のロジックは、JS 言語では、存在しない値は未定義であるということです。
しかし、オブジェクトでは次の状況も発生する可能性があります:
const obj = { name: 'Andy', age: undefined }
この場合、年齢属性は「存在する」か「存在しない」のどちらにするべきでしょうか?
それは特定の需要環境によって異なりますので、何とも言えません。
オブジェクトに age 属性があるかどうかを知る必要があると言った場合、その値が何であるかは気にしません。
次のメソッドを使用できます:
const obj = { name: 'Andy', age: 21 } console.log( Object.keys(obj).includes('age') ? '存在' : '不存在' ); // 存在
Object.keys() を使用して、判断用の独自の列挙可能なプロパティ名を取得します。
ここには 2 つのキーワードがあります。1 つは「own」、もう 1 つは「enumerable」です。
たとえば、ここにオブジェクトがあります。そのオブジェクトに属性名を追加します。
const obj = { name: 'Andy' } // `name` 就是 obj 自身的属性 console.log( Object.keys(obj) ); // [ 'name' ]
では、それ自体の属性ではないものは何でしょうか?そこで登場するのが「プロトタイプ」です。オブジェクトにはプロトタイプがあり、プロトタイプに追加された属性は「それ自体の」属性ではありません。
const obj = Object.create( { type: 'human' } ); obj.name = 'Andy'; console.log( obj.name ); // Andy console.log( obj.type ); // human console.log( Object.keys(obj) ); // [ 'name' ]
この例では、type が obj の属性であるかどうかをどのように判断しますか?これは言うのが難しいですよね?これは緩和された言語環境によって引き起こされる問題です。
しかし、知っておく必要があるのは、この場合、Object.keys() はプロトタイプのプロパティを取得できないということです。なぜなら、「独自の」プロパティしか読み取れないからです。
ここで属性記述子について説明しますが、私の同僚の多くは、JS 言語のオブジェクト内に各属性に記述子があることを知りません。
読み方は?印刷して見てみましょう:
const obj1 = { name: 'Andy', age: 21 } const obj2 = { name: 'Alice' } console.log( obj1.age ? '存在' : '不存在' ); // 存在 console.log( obj2.age ? '存在' : '不存在' ); // 不存在
この記述子は実際にはオブジェクトであり、値、書き込み可能、およびこの (列挙可能) 列挙可能な ...
などのこの属性に関する情報を記述していることがわかります。この列挙可能変数は、その属性と列挙可能かどうかを定義します。たとえば、この属性は for...in ループ中に読み取ることができ、同じことが Object.keys() にも当てはまります。
プロパティを非列挙可能として再定義すると、Object.keys() はこのプロパティを読み取ることができません。
const obj = { name: 'Baby', age: 0 } console.log( obj.age ? '存在' : '不存在' ); // 不存在
これには属性記述子に関する知識が関係します。これはネイティブ JS 言語の非常に重要な知識ですが、私の知っているフロントエンド プログラマーの多くはネイティブ JS の知識が不足していることがわかりました。
では、判定したい属性が列挙可能かどうかに関係なく、それ自体の属性だけでよい場合はどうなるでしょうか?その場合、Object.keys() は使用できません。次の方法を使用できます。
Object.hasOwn() と hasOwnProperty() の違いは何ですか?
Object.hasOwn()はES2022で追加されたメソッドで、オブジェクト自体が特定のプロパティを持っているかどうかを確認するために使用され、hasOwnPropertyの最適化処理を置き換えるために使用されます。このメソッドは後から追加されたものであるため、ブラウザの新しいバージョンだけを考慮すれば、引き続き使用できます。
これら 2 つのメソッドは "独自の" 属性名を決定するため、列挙可能かどうかに関係なく読み取ることができます。
const obj1 = { name: 'Andy', age: 21 } const obj2 = { name: 'Alice' } console.log( obj1?.age !== undefined ? '存在' : '不存在' ); // 存在 console.log( obj2?.age !== undefined ? '存在' : '不存在' ); // 不存在
なぜ Object.hasOwn() を使用するかというと、オブジェクトの hasOwnProperty() が変更される可能性があるためです。
const obj = { name: 'Andy', age: undefined }
判定したい属性名がそれ自体で列挙可能である必要がなく、プロトタイプでもよい場合は、最後の方法を使用する必要があります。
in 演算子は、プロパティがオブジェクトまたはそのプロトタイプ チェーンに存在するかどうかを判断するために使用されます。
const obj = { name: 'Andy', age: 21 } console.log( Object.keys(obj).includes('age') ? '存在' : '不存在' ); // 存在
これらの方法は、どの方法が正しいか、どちらが間違っているかを示しているわけではありません。すべてのシナリオが同じアプローチに適しているわけではないため、状況に応じてベスト プラクティスに従って、コードの可読性とセキュリティを強化してください。
以上が[すべてのブレークスルー] JavaScript にプロパティが存在するかどうかを確認する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。