2012-03-22 5 views
31

में 2 फ़ंक्शंस की तुलना कैसे करूं I जावास्क्रिप्ट में 2 फ़ंक्शंस की तुलना कैसे करूं? मैं आंतरिक संदर्भ के बारे में बात नहीं कर रहा हूं। कहोमैं जावास्क्रिप्ट

var a = function(){return 1;}; 
var b = function(){return 1;}; 

यह तुलना करने के लिए a और b संभव है?

+0

वह जावास्क्रिप्ट एक वाक्यविन्यास त्रुटि पर भी विश्लेषण नहीं करेगा ... लेकिन, "तुलना" से आपका क्या मतलब है? विभिन्न ब्राउज़र फ़ंक्शन-ऑब्जेक्ट्स पर अलग-अलग "toString" का समर्थन करते हैं, ताकि आपके मामले में काम हो सके। (लेकिन इस में नहीं क्योंकि यह पार्स नहीं करेगा इसलिए 'ए' या 'बी' को असाइन नहीं किया गया है)। मुझे यह भी लगता है कि जावास्क्रिप्ट [स्क्रिप्ट ब्लॉक में] पर "प्रतिबिंबित" करने के लिए कुछ पुस्तकालय हैं। –

+0

चूंकि सबकुछ जेएस में एक वस्तु है - आप शायद ऑब्जेक्ट तुलना की तरह smth खोजने की कोशिश कर सकते हैं (http://stackoverflow.com/questions/1068834/object-comparison-in-javascript) – shershen

उत्तर

37
var a = b = function(c){ return c; }; 
//here, you can use a === b because they're pointing to the same memory and they're the same type 

var a = function(c){ return c; }, 
    b = function(c){ return c; }; 
//here you can use that byte-saver Andy E used (which is implicitly converting the function to it's body's text as a String), 

''+a == ''+b. 

//this is the gist of what is happening behind the scences: 

a.toString() == b.toString() 
+2

ध्यान दें कि यह अनाम कार्यों के साथ काम करता है (जो , काफी उचित है, ओपी ने क्या पूछा)। यदि आपके पास var a = function a() {.... और var b = function b() {... (जो कई लोग करते हैं, क्योंकि तब आपको अपने स्टैक में अधिक सार्थक संदेश मिलते हैं) तो – gotofritz

8

आप दो चर कि समारोह संदर्भ हो सकता है अगर वे ठीक उसी समारोह का उल्लेख देखने के तुलना कर सकते हैं, लेकिन क्या तुम सच में अगर वे एक ही काम करते हैं को देखने के लिए दो अलग-अलग कार्यों तुलना नहीं कर सकते।

उदाहरण के लिए, आप यह कर सकते हैं:

function foo() { 
    return 1; 
} 

var a = foo; 
var b = foo; 

a == b; // true 

लेकिन, आप मज़बूती से ऐसा नहीं कर सकते: http://jsfiddle.net/jfriend00/SdKsu/

वहाँ:

function foo1() { 
    return 1; 
} 

function foo2() { 
    return 1; 
} 

var a = foo1; 
var b = foo2; 

a == b; // false 

आप यहाँ इस दूसरे को देख सकते हैं कुछ परिस्थितियां हैं जहां आप कार्यों पर .toString() ऑपरेटर का उपयोग कर सकते हैं, लेकिन यह आपके फ़ंक्शन के एक शाब्दिक स्ट्रिंग रूपांतरण की तुलना एक दूसरे से कर रहा है, जो मैं एफ एक छोटी सी चीज से भी दूर है जो वास्तव में जो उत्पादन करता है उसके लिए अपरिहार्य है, काम नहीं करेगा। मैं ऐसी स्थिति के बारे में सोच सकता हूं जहां मैं इसे एक विश्वसनीय तुलना तंत्र के रूप में अनुशंसा करता हूं। अगर आप इसे इस तरह से करने के बारे में गंभीरता से सोच रहे थे, तो मैं पूछूंगा क्यों? आप वास्तव में क्या करने की कोशिश कर रहे हैं और समस्या को हल करने का एक और मजबूत तरीका खोजने का प्रयास कर रहे हैं।

12

क्लोजर का मतलब है कि जब आप "तुलना" कहते हैं तो आपको बहुत सावधान रहना होगा। उदाहरण के लिए:

function closure(v) { return function(){return v} }; 
a = closure('a'); b = closure('b'); 
[a(), b()]; // ["a", "b"] 

// Now, are a and b the same function? 
// In one sense they're the same: 
a.toString() === b.toString(); // true 
// In another sense they're different: 
a() === b(); // false 

फ़ंक्शन के बाहर पहुंचने की क्षमता का अर्थ है कि सामान्य अर्थ में, कार्यों की तुलना करना असंभव है।

हालांकि, व्यावहारिक अर्थ में आप एस्प्रिमा या एकोर्न जैसे जावास्क्रिप्ट पार्सिंग पुस्तकालयों के साथ बहुत लंबा रास्ता प्राप्त कर सकते हैं। ये आपको "सार सिंटेक्स ट्री" (एएसटी) बनाने देते हैं, जो आपके प्रोग्राम का JSON विवरण है। यह डेटा के रूप में जावास्क्रिप्ट समारोह है - उदाहरण के लिए, ast अपने return 1 कार्यों इस

ast = acorn.parse('return 1', {allowReturnOutsideFunction:true}); 
console.log(JSON.stringify(ast), null, 2) 
{ 
    "body": [ 
    { 
     "argument": { 
     "value": 1,    // <- the 1 in 'return 1' 
     "raw": "1", 
     "type": "Literal" 
     }, 
     "type": "ReturnStatement" // <- the 'return' in 'return 1' 
    } 
    ], 
    "type": "Program" 
} 
// Elided for clarity - you don't care about source positions 

एएसटी सभी जानकारी की तुलना करने की जरूरत है की तरह लग रहा है। आप अपनी जरूरतों के आधार पर परिवर्तनीय नामों को सामान्य कर सकते हैं, बंद करने की जांच कर सकते हैं, तारीखों को अनदेखा कर सकते हैं।

प्रक्रिया को सरल बनाने में सहायता के लिए उपकरण और पुस्तकालयों का एक समूह है, लेकिन फिर भी, यह बहुत काम होने की संभावना है और शायद व्यावहारिक नहीं है, लेकिन यह अधिकतर संभव है। स्ट्रिंग के लिए

0

Convert समारोह है, तो, की तुलना से पहले लाइन ब्रेक और स्पेस के स्थान:

let a = function() { 
 
    return 1 
 
}; 
 

 
let b = function() { 
 
    return 1 
 
}; 
 

 
a = a.toString().replace(/\n/g, '').replace(/\s{2}/g, ' '); 
 
b = b.toString().replace(/\n/g, '').replace(/\s{2}/g, ' '); 
 

 
console.log(a); // 'function() { return 1}' 
 
console.log(b); // 'function() { return 1}' 
 
console.log(a === b); // true 
 

 
b = function() { 
 
    return 2 
 
}; 
 

 
b = b.toString().replace(/\n/g, '').replace(/\s{2}/g, ' '); 
 

 
console.log(b); // 'function() { return 2}' 
 
console.log(a === b); // false 
 

 
b =() => 3; 
 

 
b = b.toString().replace(/\n/g, '').replace(/\s{2}/g, ' '); 
 

 
console.log(b); // '() => 3' 
 
console.log(a === b); // false

पी/एस: यदि आप ES6 का उपयोग कर रहे हैं, तो var के बजाय let उपयोग करने का प्रयास । एक समारोह पर

+0

कोई रास्ता नहीं है अगर यह कार्य करता है तो यह काम नहीं करता है "फ़ंक्शन ए() {वापसी 1;}"? –

+0

@TarekSalahuddinMahmud आप फिर कोशिश कर सकते हैं। मैं बस फिर से जांचता हूँ। यह काम कर रहा है। –

0

toString() सटीक घोषणा देता है। आप इसका परीक्षण करने के लिए jfriend00 के कोड को संशोधित कर सकते हैं।

इसका मतलब है कि आप यह देखने के लिए जांच कर सकते हैं कि आपके फ़ंक्शन बिल्कुल समान हैं, जिसमें आप किस स्थान और न्यूलाइन डालते हैं।

लेकिन पहले आपको उनके नामों में अंतर को खत्म करना होगा।

function foo1() { 
    return 1; 
} 

function foo2() { 
    return 1; 
} 

//Get a string of the function declaration exactly as it was written. 
var a = foo1.toString(); 
var b = foo2.toString(); 

//Cut out everything before the curly brace. 
a = a.substring(a.indexOf("{")); 
b = b.substring(b.indexOf("{")); 

//a and b are now this string: 
//"{ 
// return 1; 
//}" 
alert(a == b); //true. 

जैसा कि अन्य ने कहा, यह अविश्वसनीय है क्योंकि अंतर का एक सफेद स्थान तुलना झूठी बनाता है।

लेकिन यदि आप इसे सुरक्षात्मक उपाय के रूप में नियोजित कर रहे हैं तो क्या होगा? ("क्या मैंने इसे बनाया है जब से मैंने अपना काम बदल दिया है?") आप वास्तव में इस तरह की सख्त तुलना की इच्छा कर सकते हैं।

संबंधित मुद्दे