JavaScriptではin
オペレータが、オブジェクトが指定されたプロパティを持つかどうかをチェックします。ただし、オブジェクトのプロパティだけでなく、プロトタイプチェーンもチェックします。したがって、状況によっては、期待どおりに動作しないことがあります。そのオブジェクトがin
演算子を使用してキーとして具体的な方法を持っている場合hasOwnProperty()の代わりにin演算子を使用する必要がある場合はありますか?
const someArrayMethods = {
indexOf: true,
map: true,
};
我々は確認することができます。
は、我々は(明らかに)キーなどの一部の配列のメソッドを含むオブジェクトsomeArrayMethods
を持っているいくつかの理由としましょう:
console.log('indexOf' in someArrayMethods); // true
console.log('every' in someArrayMethods); // false
toString
のプロパティをチェックするとどうなりますか?
console.log('toString' in someArrayMethods); // true
サプライズ!このオブジェクトのプロトタイプチェーンにはtoString
methodがあることがわかります。したがって、オブジェクトにはtoString
というプロパティがなくても、in
オペレータはtrue
を返します。
ここではhasOwnProperty()
が救助に来ます!これは、in
演算子とほとんど同じですが、1つの違いがあります。プロトタイプチェーンをチェックしません。前の例を書き換えることができます:
console.log(someArrayMethods.hasOwnProperty('toString')); // false
これは期待どおりに動作します。残念ながら、hasOwnProperty()
も1つのケースで失敗する可能性があります。もし私たちが自分の財産のオブジェクトを持っていたら、hasOwnProperty
?この例を参照してください:
const someObject = {
hasOwnProperty() {
return false;
},
theAnswer: 42,
};
// Does `someObject` has own property `theAnswer`?
console.log(someObject.hasOwnProperty('theAnswer')); // false
// Well, it seems it doesn't...
この問題を解決するために、代わりにsomeObject.hasOwnProperty
を使用して、我々はObject.prototype
から直接そのメソッドを参照することができます。
const hasOwn = Object.prototype.hasOwnProperty;
console.log(hasOwn.call(someObject, 'theAnswer')); // true
これは、かどうかをチェックするための最も合理的なアプローチであると思われますオブジェクトにはいくつかのプロパティがあります。それにもかかわらず、は、in
演算子が有用である場合があります?私はそれがいくつかのクラスのインスタンスがいくつかのメソッドを持っているかどうかをチェックするために使用できることを知っていますが、この場合、単にそのオブジェクトがそのクラスのインスタンスであるかどうかをチェックする方が良いでしょうか?サイドノートとして
、別のオプションは、ECMAScriptの2016 Array.prototype.includes()
でObject.keys()
を使用することです:
console.log(Object.keys(someObject).includes('theAnswer')); // true
機能は、いくつかのプロパティで何かを受け入れる場合 - それはプロトタイプチェーン内のプロパティが定義されている事業であってもよいが、それだけで利用可能だということではないはずです。こうすることで、実装の詳細からデータシェイプを分離できます。 – zerkms