重写Javascript中的等价比较

重写Javascript中的等价比较,javascript,operator-overloading,qunit,Javascript,Operator Overloading,Qunit,是否可以覆盖Javascript中的等价比较 最接近解决方案的方法是定义valueOf函数并在对象前面加上一个加号调用valueOf 这很有效 equal(+x == +y, true); 但这失败了 equal(x == y, true, "why does this fail."); 这是我的测试用例 var Obj = function (val) { this.value = val; }; Obj.prototype.toString = function () {

是否可以覆盖Javascript中的等价比较

最接近解决方案的方法是定义valueOf函数并在对象前面加上一个加号调用valueOf

这很有效

equal(+x == +y, true);
但这失败了

equal(x == y, true, "why does this fail.");
这是我的测试用例

var Obj = function (val) {
    this.value = val;
};
Obj.prototype.toString = function () {
    return this.value;
};
Obj.prototype.valueOf = function () {
    return this.value;
};
var x = new Obj(42);
var y = new Obj(42);
var z = new Obj(10);
test("Comparing custom objects", function () {
    equal(x >= y, true);
    equal(x <= y, true);
    equal(x >= z, true);
    equal(y >= z, true);
    equal(x.toString(), y.toString());
    equal(+x == +y, true);
    equal(x == y, true, "why does this fails.");
});
var Obj=函数(val){
this.value=val;
};
Obj.prototype.toString=函数(){
返回此.value;
};
Obj.prototype.valueOf=函数(){
返回此.value;
};
var x=新的Obj(42);
var y=新的Obj(42);
var z=新的Obj(10);
测试(“比较自定义对象”,函数(){
相等(x>=y,真);
相等(x=z,真);
相等(y>=z,真);
相等(x.toString(),y.toString());
相等(+x==+y,真);
相等(x==y,true,“为什么失败?”);
});

此处演示:

这是因为
=
操作符不只是比较原语,因此不调用
valueOf()
函数。您使用的其他运算符仅用于基本体。恐怕您无法用Javascript实现这样的功能。有关更多详细信息,请参阅。

在@Corkscreewe上搭载:

这是因为您处理的是对象,而等价运算符只比较两个变量是否引用同一个对象,而不是两个对象是否相等

一种解决方案是在变量前面使用“+”并为对象定义valueOf方法。这将调用每个对象上的valueOf方法将其值“强制转换”为一个数字。你已经发现了这一点,但可以理解的是,你似乎对它不太满意

更具表现力的解决方案可能是为对象定义一个equals函数。使用上述示例:

Obj.prototype.equals = function (o) {
    return this.valueOf() === o.valueOf();
};

var x = new Obj(42);
var y = new Obj(42);
var z = new Obj(10);

x.equals(y); // true
x.equals(z); // false

我知道这并不完全符合您的要求(重新定义等价运算符本身),但希望它能让您更接近它。

如果您正在寻找的是完整的对象比较,那么您可能希望使用类似的方法

/*
    Object.equals

    Desc:       Compares an object's properties with another's, return true if the objects
                are identical.
    params:
        obj = Object for comparison
*/
Object.prototype.equals = function(obj)
{

    /*Make sure the object is of the same type as this*/
    if(typeof obj != typeof this)
        return false;

    /*Iterate through the properties of this object looking for a discrepancy between this and obj*/
    for(var property in this)
    {

        /*Return false if obj doesn't have the property or if its value doesn't match this' value*/
        if(typeof obj[property] == "undefined")
            return false;   
        if(obj[property] != this[property])
            return false;
    }

    /*Object's properties are equivalent */
    return true;
}

您可以使用ES6
Object.is()
函数检查对象的属性

Object.prototype.equals = function(obj)
{
    if(typeof obj != "Object")
        return false;
    for(var property in this)
    {
        if(!Object.is(obj[property], this[property]))
            return false;
    }
    return true;
}
添加
()可能会根据您的要求提供帮助

var Obj = function (val) {
    this.value = val;
}();

你到底想在这里实现什么?@ElliotBonneville我正在用javascript创建分数对象。分数对象看起来像什么?我们能看到一些示例输入吗?或者我只是误解了你的意图…@ElliotBonneville基本上我是想让用户使用直接比较,而不是对对象调用比较函数。这很奇怪,因为>、=、@ElliotBonneville这是我用这些技术创建的。Ratio.js注意
NaN===NaN
为false。
==
调用ToPrimitive,如果
==
的一侧为非object,则调用valueOf。问题是
是否可以覆盖Javascript中的等价比较?