覆盖 Javascript 中的等价比较

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10539938/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 01:46:36  来源:igfitidea点击:

Override the Equivalence Comparison in Javascript

javascriptoperator-overloadingqunit

提问by Larry Battle

Is it possible to override the equivalence comparison in Javascript?

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

The closest I have gotten to a solution is by defining the valueOf function and invoking valueOf with a plus in front of the object.

我得到的最接近解决方案是定义 valueOf 函数并在对象前面使用加号调用 valueOf。

This works.

这有效。

equal(+x == +y, true);

But this fails.

但这失败了。

equal(x == y, true, "why does this fail.");

Here are my test cases.

这是我的测试用例。

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.");
});

Demo here: http://jsfiddle.net/tWyHg/5/

演示在这里:http: //jsfiddle.net/tWyHg/5/

采纳答案by Corkscreewe

That is because the ==operator doesn't compare only primitives, therefore doesn't call the valueOf()function. Other operators you used do work with primitives only. I'm afraid you cannot achieve such thing in Javascript. See http://www.2ality.com/2011/12/fake-operator-overloading.htmlfor some more details.

那是因为==运算符不只比较基元,因此不调用valueOf()函数。您使用的其他运算符仅适用于原语。恐怕您无法在 Javascript 中实现这样的目标。有关更多详细信息,请参阅http://www.2ality.com/2011/12/fake-operator-overloading.html

回答by Noah Freitas

Piggybacking on @Corkscreewe:

捎带@Corkscreewe:

This is because you are dealing with Objects and the equivalency operators are only going to compare whether two variables reference the same Object, not whether the two Objects are somehow equal.

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

One solution is to use "+" in front of the variables and define a valueOf method for the Objects. This calls the valueOf method on each object to "cast" its value to a Number. You have already found this, but understandably do not seem very satisfied with it.

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

A more expressive solution might be to define an equals function for your Objects. Using your examples above:

一个更具表现力的解决方案可能是为您的对象定义一个 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

I know this doesn't do exactly what you want (redefine the equivalency operators themselves), but hopefully it will get you a little closer.

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

回答by CBusBus

If it's full object comparison you're looking for then you might want to use something similar to this.

如果它是您正在寻找的完整对象比较,那么您可能想要使用与此类似的东西。

/*
    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;
}

回答by Khalid Azam

you can use the ES6 Object.is()function to check the property of object.

您可以使用 ES6Object.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;
}

回答by user3283513

Adding ();may help depending on your requirement.

();根据您的要求,添加可能会有所帮助。

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