2017-08-16 7 views
5

में मेरे रिकर्सन फ़ंक्शन को कॉल नहीं कर सकता मेरे पास एक ऐसा फ़ंक्शन है जो फ़ोल्डर के पेड़ के माध्यम से खोज करता है और चयनित फ़ोल्डर के मूल फ़ोल्डर को पाता है।जावास्क्रिप्ट/पॉलिमर

यहां कार्य है।

 getParentFolder: function (searchroot, childFolder) { 
      searchroot.subfolders.forEach(function (folder) { 
       if (folder.key == childFolder.key) { 
        return searchroot; 
       } 
       else { 
        if (folder.subfolders) { 
         return this.getParentFolder(folder, childFolder); 
        } 
       } 
      }); 
     } 

जब मैं this.getParentFolder(rootFolder, childFolder);

के साथ इस फोन यह बस सिर्फ मुझे देता है: Uncaught TypeError: this.getParentFolder नहीं एक समारोह क्यों है? उसी फ़ाइल में मैं अन्य कार्यों को कॉल करता हूं जो वे पूरी तरह से ठीक काम करते हैं। यह एकमात्र ऐसा कार्य है जिसे मैं कॉल करने में सक्षम हूं। क्या यह रिकर्सन की वजह से है?

उत्तर

5

आपको this को एक चर में रखना है क्योंकि आप forEach विधि के अंदर अपना संदर्भ बदलते हैं।

getParentFolder: function(searchroot, childFolder) { 
    var self = this; 
    searchroot.subfolders.forEach(function(folder) { 
    if (folder.key == childFolder.key) { 
     return searchroot; 
    } else { 
     if (folder.subfolders) { 
     return self.getParentFolder(folder, childFolder); 
     } 
    } 
    }); 
} 

इसके अलावा, return बयान जिस तरह से आप चाहते हैं काम नहीं करेगा। मैं सुझाव है कि आप पाश के लिए एक का उपयोग कर देता है की गणना करने में:

getParentFolder: function(searchroot, childFolder) { 
    for (var i = 0; i < searchroot.subfolders.length; i++) { 
    var folder = searchroot.subfolders[i]; 
    if (folder.key == childFolder.key) { 
     return searchroot; 
    } else { 
     if (folder.subfolders) { 
     return self.getParentFolder(folder, childFolder); 
     } 
    } 
    } 
} 
+0

तो क्या इसका मतलब यह है कि हर बार जब मैं इसे किसी भी लूप में बुलाता हूं क्योंकि जावास्क्रिप्ट की प्रकृति, मुझे इसे हर बार स्वयं को फिर से सौंपना है? – nanobots

+1

बिल्कुल, अगर आप मुख्य वस्तु का ट्रैक रखना चाहते हैं। वैकल्पिक रूप से, आप ['बाइंड'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) –

+1

@nanobots का उपयोग कर सकते हैं, आप बाहरी ' ''प्रत्येक' के लिए एक तर्क के रूप में जो 'स्वयं' का उपयोग करने से बचाता है। –

3

समस्या यह है कि आपके this समारोह आप forEach में पारित कर दिया के अंदर अलग है। आप आंतरिक कार्य करने के लिए बाहरी this बाध्य करने के लिए की जरूरत है:

getParentFolder: function(searchroot, childFolder) { 
    searchroot.subfolders.forEach(function(folder) { 
    if (folder.key == childFolder.key) { 
     return searchroot; 
    } else { 
     if (folder.subfolders) { 
     return this.getParentFolder(folder, childFolder); 
     } 
    } 
    }, this); // pass in outer this as context for inner function 
} 

Array.prototype.forEach() से MDN पर :

Syntax:

arr.forEach(function callback(currentValue, index, array) { 
    //your iterator 
}[, thisArg]); 

वैकल्पिक समाधान ES6 का उपयोग कर:

टिप्पणियों में उल्लिखित mishu के रूप में, नया ES6 तीर सिंटैक्स भी इस समस्या को हल करता है। ES6 में अपने कोड कुछ इस तरह दिखेगा:

getParentFolder: function(searchroot, childFolder) { 
    searchroot.subfolders.forEach((folder) => { 
    if (folder.key == childFolder.key) { 
     return searchroot; 
    } else { 
     if (folder.subfolders) { 
     return this.getParentFolder(folder, childFolder); 
     } 
    } 
    }); 
} 

तीर कार्यों this बाध्य नहीं है ES6 है (MDN देखें) तो बाहरी this तीर समारोह के भीतर से पहुँचा जा सकता है।

ध्यान दें कि सभी ब्राउज़र अभी तक तीर फ़ंक्शंस का समर्थन नहीं करते हैं (Browser compatibility on MDN देखें)। पुराने ब्राउज़र का समर्थन करने के लिए, आप Babel का उपयोग कर ईएस 5 को ईएस 5 में ट्रांसफर कर सकते हैं।

+2

नया ES6 तीर सिंटैक्स भी इस समस्या को हल नहीं करेगा, क्योंकि 'इस' पर कोई बाध्यकारी नहीं है? https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_binding_of_this – mishu

+1

@ मिशू, हां, इसमें शामिल करने के लिए मेरा उत्तर अपडेट किया गया। अच्छा सुझाव! –

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

  • कोई संबंधित समस्या नहीं^_^