2012-05-10 65 views
21

Có thể ghi đè so sánh tương đương trong Javascript không?Ghi đè so sánh tương đương trong Javascript

Gần nhất tôi đã nhận được một giải pháp là bằng cách xác định hàm valueOf và gọi valueOf với dấu cộng ở phía trước đối tượng.

Tác phẩm này.

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

Nhưng điều này không thành công.

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

Đây là các trường hợp thử nghiệm của tôi.

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 đây: http://jsfiddle.net/tWyHg/5/

+0

Chính xác bạn đang cố gắng đạt được điều gì ở đây? –

+0

@ElliotBonneville Tôi đang tạo các đối tượng phân số trong javascript. –

+0

Các đối tượng phân số trông như thế nào? Chúng ta có thể thấy một số ví dụ đầu vào? Hoặc có lẽ tôi chỉ hiểu lầm những gì bạn đang cố gắng làm ... –

Trả lời

16

Đó là bởi vì các nhà điều hành == không chỉ so sánh nguyên thủy, do đó không gọi valueOf() chức năng. Các toán tử khác mà bạn đã sử dụng chỉ làm việc với nguyên thủy. Tôi e rằng bạn không thể đạt được điều đó trong Javascript. Xem http://www.2ality.com/2011/12/fake-operator-overloading.html để biết thêm chi tiết.

+0

'==' gọi ToPrimitive gọi giá trịOf ** nếu ** một bên của '==' là nonobject – Pacerier

10

cõng trên @Corkscreewe:

này là bởi vì bạn đang đối phó với các đối tượng và các nhà khai thác tương đương chỉ đi để so sánh xem hai biến tham chiếu đến cùng một đối tượng, không phải là liệu hai đối tượng là bằng cách nào đó bằng nhau.

Một giải pháp là sử dụng "+" trước các biến và xác định phương thức valueOf cho Đối tượng. Điều này gọi phương thức valueOf trên mỗi đối tượng để "truyền" giá trị của nó thành một Số. Bạn đã tìm thấy điều này, nhưng dễ hiểu dường như không hài lòng lắm với nó.

Một giải pháp mang tính biểu cảm hơn có thể là xác định hàm bằng cho Đối tượng của bạn. Sử dụng ví dụ của bạn ở trên:

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 

Tôi biết điều này không thực hiện chính xác những gì bạn muốn (xác định lại các nhà khai thác tương đương nhau), nhưng hy vọng nó sẽ giúp bạn gần gũi hơn một chút.

+0

Care rằng 'NaN === NaN' là sai. – Pacerier

2

Nếu đó là đối sánh đầy đủ đối tượng bạn đang tìm kiếm thì bạn có thể muốn sử dụng một cái gì đó tương tự như thế này.

/* 
    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; 
} 
Các vấn đề liên quan