2012-05-10 10 views
21

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

Lo más cercano que he llegado a una solución es mediante la definición de la función valueOf y la invocación de valueOf con un signo más delante del objeto.

Esto funciona.

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

Pero esto no funciona.

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

demo aquí: http://jsfiddle.net/tWyHg/5/

+0

¿Qué es exactamente lo que intenta lograr aquí? –

+0

@ElliotBonneville Estoy creando objetos de fracción en javascript. –

+0

¿Cómo son los objetos fracción? ¿Podemos ver alguna entrada de ejemplo? O tal vez estoy malinterpretando lo que estás tratando de hacer ... –

Respuesta

16

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

+0

'==' llama a Primitivo que llama a valueOf ** if ** un lado de '==' es no objecto – Pacerier

10

montándose sobre @Corkscreewe:

Esto se debe a que se trata de objetos y los operadores de equivalencia sólo se va a comparar si dos variables hacen referencia al mismo objeto, no es si los dos objetos son de alguna manera igual.

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 "lanzar" 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 quiere (redefinir los operadores de equivalencia en sí), pero espero que le dará un poco más cerca.

+0

Atención ese 'NaN === NaN' es falso. – Pacerier

2

Si está buscando la comparación de objetos completa que está buscando, entonces es posible que desee utilizar 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; 
} 
1
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; 
} 
Cuestiones relacionadas