2012-05-10 13 views
21

में समतुल्य तुलना को ओवरराइड करें क्या जावास्क्रिप्ट में समानता तुलना को ओवरराइड करना संभव है?जावास्क्रिप्ट

मैं समाधान के लिए सबसे नज़दीक हूं, मूल्य को परिभाषित करके और ऑब्जेक्ट के सामने प्लस के साथ मूल्य का उपयोग करके मूल्य को परिभाषित करना है।

यह काम करता है।

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/

+0

वास्तव में आप यहाँ प्राप्त करने के लिए प्रयास कर रहे हैं क्या? –

+0

@ElliotBonneville मैं जावास्क्रिप्ट में अंश वस्तुएं बना रहा हूं। –

+0

अंश ऑब्जेक्ट्स कैसा दिखता है? क्या हम कुछ उदाहरण इनपुट देख सकते हैं? या हो सकता है कि मैं केवल गलत समझ रहा हूं कि आप क्या करने की कोशिश कर रहे हैं ... –

उत्तर

16

है ऐसा इसलिए है क्योंकि == ऑपरेटर केवल पुरातन तुलना नहीं करता है इसलिए valueOf() फ़ंक्शन को कॉल नहीं करता है। आपके द्वारा उपयोग किए जाने वाले अन्य ऑपरेटर केवल प्राइमेटिव के साथ काम करते हैं। मुझे डर है कि आप जावास्क्रिप्ट में ऐसी चीज हासिल नहीं कर सकते हैं। कुछ और विवरणों के लिए http://www.2ality.com/2011/12/fake-operator-overloading.html देखें। @Corkscreewe पर

+0

'==' कॉल करने के लिए कॉल करें जो कॉल करता है ** अगर ** '==' का एक पक्ष nonobject – Pacerier

10

पिगीबैकिंग:

इसका कारण यह है कि आप वस्तुओं के साथ काम कर रहे हैं और समानक ऑपरेटरों केवल तुलना करने के लिए दो चर को संदर्भित करते हों एक ही वस्तु जा रहे हैं, नहीं है कि क्या दो वस्तुओं किसी भी तरह बराबर हैं।

एक समाधान चर के सामने "+" का उपयोग करना है और ऑब्जेक्ट्स के लिए एक मानऑफ विधि परिभाषित करना है। यह प्रत्येक ऑब्जेक्ट पर valueOf विधि को अपने मान को "संख्या" पर रखने के लिए कॉल करता है। आप इसे पहले ही पा चुके हैं, लेकिन समझ में नहीं आता है कि इससे बहुत संतुष्ट नहीं है।

आपके ऑब्जेक्ट्स के लिए एक समान कार्य को परिभाषित करने के लिए एक अधिक अभिव्यक्तिपूर्ण समाधान हो सकता है। ऊपर अपने उदाहरण का उपयोग करना:

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 

जानते हैं कि यह वास्तव में आप क्या चाहते हैं नहीं करता है मैं (समानक ऑपरेटरों खुद को फिर से परिभाषित), लेकिन उम्मीद है कि यह आपको थोड़ा बढ़ जाएगी।

+0

देखभाल है कि 'NaN === NaN' गलत है। – Pacerier

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