JavaScript में कार्यात्मक प्रोग्रामिंग: A से Z तक
\n\nकार्यात्मक प्रोग्रामिंग (FP) एक प्रतिमान है जो गणना को गणितीय फ़ंक्शनों की गणना के रूप में मानता है और स्थिति और परिवर्तनीय डेटा में बदलाव से बचता है। JavaScript (Node.js) के संदर्भ में, FP पूर्वानुमानित, परीक्षण योग्य और स्केलेबल कोड बनाने के लिए एक शक्तिशाली उपकरण बन जाता है। इस लेख में, हम FP की मुख्य अवधारणाओं को बुनियादी से लेकर उन्नत तकनीकों तक, सिद्धांत को व्यावहारिक उदाहरणों के साथ समझेंगे।
\n\nमूल बातें: शुद्ध फ़ंक्शन और इम्यूटेबिलिटी
\n\nFP के मूल में दो सिद्धांत हैं: शुद्ध फ़ंक्शन और इम्यूटेबिलिटी (डेटा की अपरिवर्तनीयता)।
\n\nशुद्ध फ़ंक्शन हमेशा समान तर्कों के लिए समान परिणाम देता है और इसका कोई दुष्प्रभाव नहीं होता (बाहरी चर नहीं बदलता, कंसोल में आउटपुट नहीं देता, API अनुरोध नहीं करता)।
\n\n// शुद्ध फ़ंक्शन\nconst add = (a, b) => a + b;\n\n// अशुद्ध फ़ंक्शन (दुष्प्रभाव — बाहरी चर बदलना)\nlet counter = 0;\nconst increment = () => counter++;\n\n\nइम्यूटेबिलिटी का अर्थ है कि डेटा को सीधे नहीं बदला जाता, बल्कि आवश्यक परिवर्तनों के साथ उनकी नई प्रतियाँ बनाई जाती हैं। JavaScript में इसके लिए ऐसी विधियों का उपयोग किया जाता है जो नई वस्तुएँ/सरणियाँ लौटाती हैं।
\n\n// ऑब्जेक्ट का इम्यूटेबल अपडेट\nconst user = { name: 'Alice', age: 30 };\nconst updatedUser = { ...user, age: 31 }; // नया ऑब्जेक्ट बनाएँ\n\n// ऐरे का इम्यूटेबल अपडेट\nconst numbers = [1, 2, 3];\nconst newNumbers = [...numbers, 4]; // [1, 2, 3, 4]\n\n\nक्लोज़र और उच्च-क्रम फ़ंक्शन
\n\nक्लोज़र एक ऐसा फ़ंक्शन है जो अपने लेक्सिकल एनवायरनमेंट को "याद" रखता है, भले ही बाहरी फ़ंक्शन का निष्पादन समाप्त हो गया हो। यह FP के कई पैटर्न का आधार है।
\n\nconst createMultiplier = (factor) => {\n // आंतरिक फ़ंक्शन — क्लोज़र\n return (number) => number * factor;\n};\n\nconst double = createMultiplier(2);\nconsole.log(double(5)); // 10\n\n\nउच्च-क्रम फ़ंक्शन वे फ़ंक्शन हैं जो अन्य फ़ंक्शनों को तर्क के रूप में लेते हैं या उन्हें लौटाते हैं। क्लासिक उदाहरण हैं map, filter, reduce।
const numbers = [1, 2, 3, 4, 5];\n\n// map — प्रत्येक तत्व को रूपांतरित करता है\nconst doubled = numbers.map(n => n * 2); // [2, 4, 6, 8, 10]\n\n// filter — शर्त के अनुसार तत्वों का चयन करता है\nconst even = numbers.filter(n => n % 2 === 0); // [2, 4]\n\n// reduce — ऐरे को एक मान में समेटता है\nconst sum = numbers.reduce((acc, n) => acc + n, 0); // 15\n\n\nफ़ंक्शन कम्पोज़ीशन और करीइंग
\n\nफ़ंक्शन कम्पोज़ीशन कई फ़ंक्शनों को एक में जोड़ना है, जहाँ एक फ़ंक्शन का परिणाम अगले फ़ंक्शन के इनपुट के रूप में जाता है। यह सरल, पुन: प्रयोज्य ब्लॉकों से जटिल संचालन बनाने की अनुमति देता है।
\n\nconst compose = (...fns) => (x) => fns.reduceRight((acc, fn) => fn(acc), x);\n\nconst trim = (str) => str.trim();\nconst toLowerCase = (str) => str.toLowerCase();\nconst capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);\n\nconst processName = compose(capitalize, toLowerCase, trim);\nconsole.log(processName(' JOHN DOE ')); // 'John doe'\n\n\nकरीइंग कई तर्कों वाले फ़ंक्शन को फ़ंक्शनों के अनुक्रम में बदलना है, जिनमें से प्रत्येक एक तर्क लेता है। यह आंशिक अनुप्रयोग और कम्पोज़ीशन को सरल बनाता है।
\n\n// सामान्य फ़ंक्शन\nconst multiply = (a, b, c) => a * b * c;\n\n// करीड संस्करण\nconst curriedMultiply = (a) => (b) => (c) => a * b * c;\n\nconsole.log(curriedMultiply(2)(3)(4)); // 24\n\n// आंशिक अनुप्रयोग\nconst multiplyBy2 = curriedMultiply(2);\nconst multiplyBy2And3 = multiplyBy2(3);\nconsole.log(multiplyBy2And3(5)); // 30\n\n\n