Вопрос по javascript – Переопределить сравнение эквивалентности в Javascript

30

Можно ли переопределить сравнение эквивалентности в 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.");
});

Демо здесь:http://jsfiddle.net/tWyHg/5/

@ElliotBonneville Вот что я создал, используя эти методы. Ratio.jsgithub.com/LarryBattle/Ratio.js Larry Battle
Что именно вы пытаетесь достичь здесь? Elliot Bonneville
@ElliotBonneville В основном я пытался разрешить пользователю использовать прямые сравнения вместо вызова функции сравнения на объектах. Это странно, потому что & gt ;, & lt ;, & gt; =, & lt; = работает, но только не ==. Larry Battle
Как выглядят объекты дроби? Можем ли мы увидеть некоторые примеры ввода? Или, может быть, я просто неправильно понимаю, что вы пытаетесь сделать ... Elliot Bonneville
@ElliotBonneville Я создаю дробные объекты в javascript. Larry Battle

Ваш Ответ

4   ответа
2

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

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;
}
2

Если вы ищете полное сравнение объектов, то вы можете использовать что-то похожее на это.

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

Спекуляция на @Corkscreewe:

Это потому, что вы имеете дело с объектами, а операторы эквивалентности будут сравнивать только то, ссылаются ли две переменные на один и тот же объект, а не равны ли эти два объекта.

Одним из решений является использование "+" перед переменными и определите метод valueOf для объектов. При этом для каждого объекта вызывается метод valueOf для «cast» его значение для числа. Вы уже нашли это, но по понятным причинам, кажется, не очень довольны этим.

Более выразительным решением может быть определение функции равенства для ваших Объектов. Используя ваши примеры выше:

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

Я знаю, что это не делает именно то, что вы хотите (переопределите сами операторы эквивалентности), но, надеюсь, это немного приблизит вас.

Error: User Rate Limit ExceededNaN === NaNError: User Rate Limit Exceeded
19

Это потому что== оператор не сравнивает только примитивы, поэтому не вызываетvalueOf() функция. Другие используемые вами операторы работают только с примитивами. Я боюсь, что вы не можете достичь этого в Javascript. Увидетьhttp://www.2ality.com/2011/12/fake-operator-overloading.html для более подробной информации.

==Error: User Rate Limit ExceededifError: User Rate Limit Exceeded==Error: User Rate Limit Exceeded

Похожие вопросы