JavaScriptのObjectが等しい(翻訳文)
3098 ワード
出所:Object Equality in JavaScript
同じようにJavaScriptの中で最初に最も困惑した部分です.
二つのobjectが同じ属性を持っていて、それらの多くの属性値が同じなら、この二つのobjectは同じであるべきだと思うかもしれません.私達が予想した通りかどうか見てみましょう.
したがって、オブジェクトが同じであることを検証するには、どのように等しいかを確認する必要があります.二つのインスタンスが完全に同じかどうかを検証するためには、JavaScriptに内蔵されている等しい演算子を使用することができます.あるいは、二つのインスタンスが「同じ値」を持っていることを検証したいです.そうすると、もっと仕事をしなければならないかもしれません.
以下はobjectの「値が等しい」を検査する基本的な実現である.もしある属性がobject であれば属性値がある場合 は、 .
objectのインスタンス「値が等しい」を検証するための丈夫な方法がほしいです.様々な境界状況をカバーする全面的なテストを経たライブラリを使用したほうがいいです.UnderscoreとLo-Dashの2つのライブラリの
同じようにJavaScriptの中で最初に最も困惑した部分です.
==
と===
の比較、強制タイプの順序などは、この問題を複雑にしている.今日はもう一つの面に焦点を合わせます.objectはどうやって実現しますか?二つのobjectが同じ属性を持っていて、それらの多くの属性値が同じなら、この二つのobjectは同じであるべきだと思うかもしれません.私達が予想した通りかどうか見てみましょう.
var jangoFett = {
occupation: "Bounty Hunter",
genetics: "superb"
};
var bobaFett = {
occupation: "Bounty Hunter",
genetics: "superb"
};
// Outputs: false
console.log(bobaFett === jangoFett);
bobaFett
とjangoFett
の属性は全く同じですが、2つのobjectは同じとは思いません.恒などの演算子を使う理由ですか?検証してみます.// Outputs: false
console.log(bobaFett == jangoFett);
私たちがそうしているのは、JavaScript内部には2つの異なる案があり、これを検証しているからです.文字列や数値のような基本的なタイプは、それらの値に基づいて比較されます.しかし、配列、日付、および簡単なオブジェクトのようなobjectは、それらの参照に基づいて判断される.参照によって、与えられたobjectがメモリ中の同じアドレスを指すかどうかを確認します.以下の例では、JavaScriptにおける等価演算子の実現原理を説明します.var jangoFett = {
occupation: "Bounty Hunter",
genetics: "superb"
};
var bobaFett = {
occupation: "Bounty Hunter",
genetics: "superb"
};
var callMeJango = jangoFett;
// Outputs: false
console.log(bobaFett === jangoFett);
// Outputs: true
console.log(callMeJango === jangoFett);
一態様では、jangoFett
およびbobaFett
の2つの変数は、完全に同じ属性を持つ2つのobjectから参照されるが、確かに2つの異なる例である.一方、jangoFett
およびcallMeJango
は同じ例を指す.したがって、オブジェクトが同じであることを検証するには、どのように等しいかを確認する必要があります.二つのインスタンスが完全に同じかどうかを検証するためには、JavaScriptに内蔵されている等しい演算子を使用することができます.あるいは、二つのインスタンスが「同じ値」を持っていることを検証したいです.そうすると、もっと仕事をしなければならないかもしれません.
以下はobjectの「値が等しい」を検査する基本的な実現である.
function isEquivalent(a, b) {
// Create arrays of property names
var aProps = Object.getOwnPropertyNames(a);
var bProps = Object.getOwnPropertyNames(b);
// If number of properties is different,
// objects are not equivalent
if (aProps.length != bProps.length) {
return false;
}
for (var i = 0; i < aProps.length; i++) {
var propName = aProps[i];
// If values of same property are not equal,
// objects are not equivalent
if (a[propName] !== b[propName]) {
return false;
}
}
// If we made it this far, objects
// are considered equivalent
return true;
}
// Outputs: true
console.log(isEquivalent(bobaFett, jangoFett));
あなたが見ているように、objectのインスタンスの「値が等しい」を検証したいです.私たちはobjectの各属性を遍歴して、それが等しいかどうかを確認しなければなりません.上で実現したこの簡単な方案を私達の例に適用すれば、多くの場合はまだ処理されていません.たとえば:NaN
(JavaScriptの中の唯一の自身が自身の値に等しくない)a
に属性がある値がundefined
である場合、b
にはこの属性がない(したがって、全部undefined
と同じ)objectのインスタンス「値が等しい」を検証するための丈夫な方法がほしいです.様々な境界状況をカバーする全面的なテストを経たライブラリを使用したほうがいいです.UnderscoreとLo-Dashの2つのライブラリの
_.isEqual
方法は、処理objectの深さ比較を良好に実施した.このようにそれらを使ってもいいです.// Outputs: true
console.log(_.isEqual(bobaFett, jangoFett));
このJavaScriptの小さな知識点が、objectの実例と同等の実現原理をよりよく理解するのに役立つことを願っています.