我有一个自定义的Javascript类(使用John Resig的简单Javascript继承创建)。我想能够比较这个类的两个实例,使用 ==
,<
,>
,> =
和<=
符号。
如何覆盖我的自定义类的比较器?
我有一个自定义的Javascript类(使用John Resig的简单Javascript继承创建)。我想能够比较这个类的两个实例,使用 ==
,&lt;
,>
,> =
和<=
符号。
如何覆盖我的自定义类的比较器?
尝试重写valueOf()。然后你就可以编写类似于这样的内容:
if (obj1.valueOf() === obj2.valueOf())
if (obj1.valueOf() < obj2.valueOf())
if (obj1.valueOf() > obj2.valueOf())
所以每当我需要一个特殊的JavaScript对象类型来覆盖比较时,我只需将valueOf添加到原型中。对于基本类型也非常有效,因为valueOf只返回该值。只需注意空值。Lee是正确的,如果你实现了valueOf方法,那么在比较对象时(不使用===或!==),将会调用该方法,但是你也必须使用toString方法,因为它在某些情况下用于排序数组。
function Test(value){
this.value=value;
}
Test.prototype.toString=function(){
console.log("tostring called");
// could do something with case sensitiveness here
return new String(this.valueOf());
}
Test.prototype.valueOf=function(){
console.log("valueof called");
return this.value;
}
var t1=new Test(11);
var t2=new Test(1.1);
var arr=[t1,t2];
console.log('sorted',arr.sort().map(o=>o.value));
console.log('larger',t1>=t2);
这不能按照你意图的方式完成(虽然那样会很好),我见过的最佳方法是在原型上实现一组行为类比的方法:
gte : function( obj ){ // greater than or equal
// return custom comparison with this as the object comparable on the left
},
gt : function( obj ){...}, // greater than but not equal
eq : function( obj ){...}, // equal to
// etc.
今天在工作中我进一步思考了这个问题,并且有一种替代方式可以利用标准比较运算符,但是具有自定义对象比较。窍门是在对象上有一个表示可比状态的属性(getter)。这将要求对象的所有实例在给定相同可比属性时评估为相同的数字值。举个例子,我们来谈谈向量:
function Vector(x,y,z){
this.comp = function(){
// assuming these are floats you may wish to create a comparable level of
// precision. But this gets the point across.
return x + (y * 10) + (z * 100);
}
}
那么当您设置向量时:
var v1 = new Vector(1,1,1);
var v2 = new Vector(1,0,1);
v1.comp() > v2.comp() // true
当然,这仅适用于可以分解为简单数值表达式的对象,但好处是实现基本效果的代码非常少,甚至可以将对象本身作为返回其组件部分的数值表达式的函数。
function Vector(x,y,z){
var v = function v(){
return v.x + (v.y * 10) + (v.z * 100);
}
v.x = x;
v.y = y;
v.z = z;
return v;
}
=
不是比较运算符,而是赋值运算符。 - Peter Olson:)
- Šime Vidas