admin管理员组文章数量:1314246
I'm trying to implement custom equality and relational operations using equals and pareTo methods. However, I get wrong results. Please help me figure our where I'm doing wrong.
var Person = function () {
this.age = null;
this.name = null;
};
Person.prototype.equals = function (that) {
if (this.age === that.age) return true;
else return false;
};
Person.prototypepareTo = function (that) {
return this.age - that.age;
};
var p1 = new Person();
var p2 = new Person();
p1.age = 10;
p2.age = 20;
document.writeln(p1 < p2); // this should be true but evaluates to false.
I'm trying to implement custom equality and relational operations using equals and pareTo methods. However, I get wrong results. Please help me figure our where I'm doing wrong.
var Person = function () {
this.age = null;
this.name = null;
};
Person.prototype.equals = function (that) {
if (this.age === that.age) return true;
else return false;
};
Person.prototype.pareTo = function (that) {
return this.age - that.age;
};
var p1 = new Person();
var p2 = new Person();
p1.age = 10;
p2.age = 20;
document.writeln(p1 < p2); // this should be true but evaluates to false.
Share
Improve this question
asked Jul 28, 2015 at 14:25
user1176058user1176058
6761 gold badge9 silver badges23 bronze badges
2 Answers
Reset to default 7JavaScript doesn't have operator overloading, and >
doesn't call any methods on your objects, so p1 < p2
won't use your equals
or pareTo
.
To do that parison, you'd use:
document.writeln(p1.pareTo(p2) < 0);
That said, you can implement valueOf
and have it return age
. valueOf
does get called as part of >
between objects:
function Person(age) {
this.age = age;
this.name = null;
}
Object.defineProperty(Person.prototype, "valueOf", {
value: function () {
return this.age;
},
writable: true,
configurable: true,
});
Or in code written since ES2015 became universally-supported in non-obsolete browsers:
class Person {
constructor(age) {
this.age = age;
this.name = null;
}
valueOf() {
return this.age;
}
}
Live Example:
class Person {
constructor(age) {
this.age = age;
this.name = null;
}
valueOf() {
return this.age;
}
}
const p1 = new Person(10);
const p2 = new Person(20);
console.log("p1 < p2: " + (p1 < p2)); // true
console.log("p1 > p2: " + (p1 > p2)); // false
Beware though that p1 == p2
and p1 === p2
will always be false
, even if age
is the same:
class Person {
constructor(age) {
this.age = age;
this.name = null;
}
valueOf() {
return this.age;
}
}
const p1 = new Person(10); // Same age
const p2 = new Person(10); // Same age
console.log("p1 == p2: " + (p1 == p2)); // false!
console.log("p1 === p2: " + (p1 === p2)); // false!
valueOf
is invoked when the JavaScript engine needs to convert the object to a primitive; it doesn't do that for ==
or ===
unless it has to because the other operand is a primitive. So you'd have to define equals
and explicitly call it (p1.equals(p2)
), or force the parison to be between the primitives (+p1 === +p2
), which is error-prone.
Revisiting this question and working with node v18.13.0, I found that relational operators between objects invoke the valueOf
method, and if not available, then invoke the toString
method. A String
representation can be built to allow parison of most object types (assuming you can build the String representation as needed).
The following example illustrates all these cases by menting in/out the two versions of toString
or the valueOf
method:
import assert from 'node:assert/strict';
export class ComparableDate {
// private instance variables
#year
#month
#date
constructor(year, month, date) {
this.#year = year;
this.#month = month;
this.#date = date;
}
// Relational operators > < invoke the toString method.
// Observe that this fails for paring dates in general
// toString() {
// console.log("toString invoked");
// return ""+this.#year+"-"+this.#month+"-"+this.#date;
// }
// Zero-left padding, makes the string parison work as expected
toString() {
console.log("toString invoked");
return (""+this.#year).padStart(4,'0')+"-"+(""+this.#month).padStart(2,'0')+"-"+(""+this.#date).padStart(2,'0');
}
// valueOf called over toString if present
valueOf() {
console.log("valueOf invoked");
return this.#date + this.#month*31 + this.#year*366;
}
}
// Test dates
let d1 = new ComparableDate(2023,2,15);
let d2 = new ComparableDate(2023,10,31);
// Test cases
assert(d2>d1, `${d2} must be greater than ${d1}`);
assert(d1<d2, `${d1} must be less than ${d2}`);
本文标签: Object comparison in Javascript using equals and compareTo methodsStack Overflow
版权声明:本文标题:Object comparison in Javascript using equals and compareTo methods - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741965553a2407525.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论