2011-04-11 61 views
7

我有一個自定義Javascript類(使用John Resig's Simple Javascript Inheritance創建)。我希望能夠使用==,<,>,>=<=符號來比較此類的兩個實例。覆蓋JavaScript中比較運算符的默認行爲

如何覆蓋我的自定義類的比較器?

+0

在Javascript中,'='不是比較器,它是賦值運算符。 – 2011-04-11 21:27:11

+0

糟糕,錯字。感謝您的支持。 – Chetan 2011-04-11 21:29:46

+1

查看本文的底部:*「我正在編寫的這本書將深入討論這個話題:JavaScript忍者的祕密。將於2008年秋季發佈。」* - 仍然未發佈,Resig的書是公爵永遠的JavaScript':'' – 2011-04-11 21:33:29

回答

3

這不能以你暗示應該完成的方式來完成(儘管這樣會很好)。我已經看到這種情況,最好的辦法是在原型上實現了一套方法來像對比:

gte : function(obj){ // greater than or equal 
    // return custom comparison with this as the object comparable on the left 
}, 
gt : function(obj){...}, // greater than but not equal 
eq : function(obj){...}, // equal to 
// etc. 

我somemore今天工作在思考這個問題並沒有充分利用的替代方法標準比較運算符,但具有自定義對象比較。訣竅是在表示可比較狀態的對象上有一個屬性(getter)。這將要求對象的所有實例都使用相同的可比較屬性評估相同的數值。作爲例子,讓我們來談談載體:

function Vector(x,y,z){ 
    this.comp = function(){ 
    // assuming these are floats you may wish to create a comparable level of 
    // precision. But this gets the point across. 
    return x + (y * 10) + (z * 100); 
    } 
} 

那麼當你設置載體:

var v1 = new Vector(1,1,1); 
var v2 = new Vector(1,0,1); 
v1.comp() > v2.comp() // true 

當然,這僅適用於如果你正在處理,可以細分爲價值簡單的數字表達式對象,但好處是獲得基本效果的實現代碼非常低,甚至可以讓對象本身成爲一個返回其組成部分的數字表達式的函數。

function Vector(x,y,z){ 
    var v = function v(){ 
    return v.x + (v.y * 10) + (v.z * 100); 
    } 
    v.x = x; 
    v.y = y; 
    v.z = z; 
    return v; 
} 

現在,您可以通過簡單的數字比較獲得對象的所有優點,它甚至有點簡潔。

+0

我很懷疑:/無論如何。 – Chetan 2011-04-11 21:33:26

+0

前一段時間,我看到了一種哈哈的方式來達到Javascript重載操作符:http://blogger.xs4all.nl/peterned/archive/2009/04/01/462517。aspx我一直想嘗試一下,看看我能不能改善它,但我從來沒有接受過。 – 2011-04-11 21:33:32

+0

@PeterOlson鏈接不再起作用。我想讀一讀,如果你發現它會重新發布嗎?謝謝。 – Gabriel 2013-02-19 17:26:30

8

嘗試覆蓋valueOf()。然後,你可以寫這樣的東西:

if (obj1.valueOf() === obj2.valueOf()) 
if (obj1.valueOf() < obj2.valueOf()) 
if (obj1.valueOf() > obj2.valueOf()) 

所以每當我需要一個特殊的JavaScript對象類型覆蓋的比較,我只是添加的valueOf原型。它對原始類型也很好,因爲valueOf只是返回值。

只要注意空位。

+2

valueOf的好處是你不需要明確地調用它obj1> obj2會爲你調用valueOf。當對數組進行排序時,toString有時被調用(在FF上),所以也要實現這一點。 – HMR 2013-08-28 00:04:54

3

Lee是正確的,如果你實現了valueOf,那麼當比較對象時(不是===或!===),這將被使用,但是你也必須使用toString,因爲它用於對一些數組進行排序原因。

function Test(value){ 
    this.value=value; 
} 
Test.prototype.toString=function(){ 
    console.log("tostring called"); 
    // could do something with case sensitiveness here 
    return new String(this.valueOf()); 
} 
Test.prototype.valueOf=function(){ 
    console.log("valueof called"); 
    return this.value; 
} 

var t1=new Test(11); 
var t2=new Test(1.1); 
var arr=[t1,t2]; 
console.log(arr.sort()); 
console.log(t1>=t2);