javascript operator-overloading qunit

Anular la comparación de equivalencia en Javascript



operator-overloading qunit (4)

Esto se debe a que el operador == no compara solo los primitivos, por lo tanto, no llama a la función valueOf() . Otros operadores que usaste trabajan solo con primitivos. Me temo que no se puede lograr tal cosa en Javascript. Consulte http://www.2ality.com/2011/12/fake-operator-overloading.html para obtener más detalles.

¿Es posible anular la comparación de equivalencia en Javascript?

Lo más cercano que he llegado a una solución es definir la función valueOf e invocar valueOf con un signo más delante del objeto.

Esto funciona.

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

Pero esto falla.

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

Aquí están mis casos de prueba.

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

Demostración aquí: http://jsfiddle.net/tWyHg/5/


Piggybacking en @Corkscreewe:

Esto se debe a que está tratando con Objetos y los operadores de equivalencia solo van a comparar si dos variables hacen referencia al mismo Objeto, no si los dos Objetos son de alguna manera iguales.

Una solución es usar "+" delante de las variables y definir un método valueOf para los Objetos. Esto llama al método valueOf en cada objeto para "convertir" su valor a un Número. Ya has encontrado esto, pero es comprensible que no parezcas muy satisfecho con él.

Una solución más expresiva podría ser definir una función igual para sus objetos. Usando sus ejemplos anteriores:

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

Sé que esto no hace exactamente lo que quieres (redefine los operadores de equivalencia en sí mismos), pero espero que te acerque un poco más.


Si lo que buscas es la comparación de objetos completa, es posible que desees usar algo similar a esto.

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


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