چگونه میتوان برابری دو شی در جاوااسکریپت را تشخیص داد؟
در جاوااسکریپت استفاده از عملگرهای مقایسه درونی بر روی اشیا برای بررسی برابری تنها روی رفرنس اشیا عمل می کند. برای مثال اگر دو شی از کلاس شخص داشته باشید که شناسه آنها یکسان باشد ولی رفرنس یکسان نداشته باشند، مقدار فالس برمی گردانند. برای تشخیص برابری دو شی در جاوااسکریپت می توانیم به یکی از روش های زیر عمل کنیم:
۱. استفاده از توابع کتابخانهای مانند Lodash:
یکی از سادهترین و مؤثرترین روشها استفاده از تابع _.isEqual در Lodash است. این متد به مرور زمان بهینه شده و با استفاده از بهینهسازیهای ECMAScript کارایی بالایی دارد.
_.isEqual(object1, object2);
۲. استفاده از متد سفارشی برای کلاس ها:
شما میتوانید خودتان تابعی برای مقایسه دو شی از یک کلاس پیادهسازی کنید. این متد میتواند ویژگیهای مهم دو شی را مقایسه کند. برای مثال، در زیر یک مثال با استفاده از کلاس Card آورده شده است:
function Card(rank, suit) {
this.rank = rank;
this.suit = suit;
this.equals = function(other) {
return other.rank === this.rank && other.suit === this.suit;
};
}
var queenOfClubs = new Card(12, "C");
var kingOfSpades = new Card(13, "S");
queenOfClubs.equals(kingOfSpades); // => false
kingOfSpades.equals(new Card(13, "S")); // => true
مقایسه بر اساس رشته JSON:
یکی دیگر از روش ها استفاده از JSON.stringify برای تولید رشته JSON اشیاست که دو عیب دارد. اول اینکه ممکن است باعث بالا رفتن زمان مقایسه نسبت به سایر روشها شود. دوم اینکه اگر ترکیب قرارگیری پراپرتی ها با هم فرق داشته باشد جواب اشتباه میدهد.
var a = { a: 1, b: 2}
var b = { b: 2, a: 1 }
JSON.stringify(b) === JSON.stringify(a) // -> false
// b => '{"b":2,"a":1}'
// a => '{"a":1,"b":2}'
استفاده از تابع بررسی عمیق
راه دیگر استفاده از یک تابع سفارشی برای بررسی عمیق (ویژگی به ویژگی) دو شی است. برای مثال در زیر تابعی با نام deepEqual نوشته شده است که این کار را انجام می دهد:
function deepEqual(x, y) {
const ok = Object.keys, tx = typeof x, ty = typeof y;
return x && y && tx === 'object' && tx === ty ? (
ok(x).length === ok(y).length &&
ok(x).every(key => deepEqual(x[key], y[key]))
) : (x === y);
}
توجه داشته باشید که ممکن است این تابع همه حالت های ممکن را مورد بررسی قرارنداده باشد و در برخی موارد جواب نادرست برگرداند.