Skip to content
This page has been auto-translated and may contain errors.View in English

फंक्शन

docs.scrimba.com

मान लीजिए कि आप कार्ट में आइटम की कीमत निर्धारित कर रहे हैं। आप एक संख्या लेते हैं, टैक्स जोड़ते हैं, इसे राउंड करते हैं, और इसे करेंसी प्रतीक के साथ फॉर्मेट करते हैं। फिर आपको अगली आइटम के लिए यह फिर से करना है, और अगली के लिए भी। इन चार चरणों को हर जगह कॉपी करना यही है कि कैसे बग आते हैं: एक जगह राउंडिंग को ठीक करें और आपके पास अभी भी तीन और कॉपी गलत हैं। एक फंक्शन आपको उन चरणों के ब्लॉक को एक बार नाम देने देता है और जब भी आपको इसकी आवश्यकता हो तब चलाता है। यह अध्याय उन ब्लॉकों को लिखने, उन्हें इनपुट देने, और वैल्यू वापस पाने के बारे में है।

फंक्शन घोषित करना और कॉल करना

एक फंक्शन कोड का एक नामित ब्लॉक है जिसे आप जब चाहें चला सकते हैं। आप चरणों को एक बार लिखते हैं, उन्हें एक नाम देते हैं, और फिर उस नाम से जितनी बार चाहें उन्हें चलाते हैं।

आप function कीवर्ड के साथ एक बनाते हैं:

js
function greet() {
  console.log("Hi there");
}

यह पूरी परिभाषा है, लेकिन अभी तक कुछ नहीं हुआ है। एक फंक्शन लिखने से चरण संग्रहीत होते हैं; यह उन्हें नहीं चलाता है। इसे वास्तव में चलाने के लिए, आप इसे अपने नाम के बाद कोष्ठक लिखकर कॉल करते हैं:

js
greet(); // Hi there
greet(); // Hi there

दो लाइनें, दो अभिनंदन, एक कोड ब्लॉक से। परिभाषित करना और कॉल करना अलग-अलग चीजें हैं, और उन्हें मिलाना पहली चीज है जो लोगों को परेशान करती है।

एक फंक्शन एक नाम के तहत कोड के एक ब्लॉक को लपेटता है ताकि आप इसे मांग पर चला सकें। आप इसे function कीवर्ड के साथ एक बार परिभाषित करते हैं, फिर इसे जितनी बार आपको आवश्यकता हो कॉल करते हैं:

js
function logDivider() {
  console.log("----------");
}

logDivider(); // ----------
logDivider(); // ----------

परिभाषा चरणों को सेट करती है लेकिन कुछ नहीं चलाती है। एक फंक्शन केवल तभी चलता है जब आप इसे () से कॉल करते हैं। अपने आप नाम, logDivider, फंक्शन वैल्यू है; कोष्ठक वह है जो इसे आह्वान करता है। यह अंतर महत्वपूर्ण है जब से आप फंक्शन को चारों ओर पास करना शुरू करते हैं, क्योंकि logDivider और logDivider() दो अलग-अलग चीजें हैं: एक फंक्शन है, दूसरा इसे चलाने का परिणाम है।

एक फंक्शन एक नाम के लिए बाध्य कोड का एक पुनः प्रयोज्य ब्लॉक है। function कीवर्ड यहां एक फंक्शन घोषणा बनाता है: एक नामित फंक्शन जो अपने स्कोप के शीर्ष पर hoisted है, जिसका अर्थ है कि आप इसे जहां आपने लिखा है उसके ऊपर की लाइन पर कॉल कर सकते हैं और यह अभी भी काम करता है।

js
countdown(); // works: declarations are hoisted

function countdown() {
  console.log("Ready");
}

वह hoisting घोषणा फॉर्म के लिए विशिष्ट है; इस अध्याय में फंक्शन को परिभाषित करने के अन्य तरीके इसे साझा नहीं करते हैं। नाम और कॉल अलग-अलग वैल्यूज हैं: countdown फंक्शन स्वयं का मूल्यांकन करता है (आप इसे स्टोर कर सकते हैं, पास कर सकते हैं, तुलना कर सकते हैं), जबकि countdown() फंक्शन को चलाने का मूल्यांकन करता है। दोनों को मिलाना "यह undefined क्यों है" भ्रम का एक बड़ा हिस्सा है, और उन्हें अलग रखना एक आदत है जो अब बनाने योग्य है, इससे पहले कि फंक्शन को अन्य फंक्शन के तर्क के रूप में पास करना शुरू हो।

फंक्शन को एक स्पष्ट, क्रिया-जैसा नाम दें कि यह क्या करता है (greet, logDivider), वही देखभाल जो आप नामकरण चर करते समय लेते हैं। एक फंक्शन जिसे आप दस जगहों पर कॉल करते हैं केवल इसके नाम जितना पठनीय है।

Junoफंक्शन घोषित करना और कॉल करना एक फंक्शन लिखने से चरण संग्रहीत होते हैं; यह उन्हें नहीं चलाता है। इसे चलाने के लिए, आप इसे कोष्ठक के साथ नाम से कॉल करते हैं, जैसे greet()। यह विभाजन मुझे पहले भ्रमित करता था: परिभाषा नुस्खा है, कॉल वास्तव में खाना बना रहा है। आप एक ही फंक्शन को जितनी बार चाहें कॉल कर सकते हैं।
Junoफंक्शन घोषित करना और कॉल करना एक फंक्शन को परिभाषित करना और कॉल करना दो अलग-अलग कार्य हैं। function ब्लॉक चरणों को सेट करता है और जब तक आप () जोड़ते हैं तब तक कुछ नहीं चलाता है। अपने सिर में greet और greet() को सीधा रखें: एक फंक्शन वैल्यू है, दूसरा इसे चलाने का परिणाम है। वह अंतर पहली बार काटता है जब आप कहीं एक फंक्शन पास करते हैं।
Junoफंक्शन घोषित करना और कॉल करनाfunction कीवर्ड एक घोषणा बनाता है, जो hoists है, इसलिए आप इसे जहां बैठता है उसके ऊपर कॉल कर सकते हैं। यह इस फॉर्म के लिए अद्वितीय है; expressions और arrows समान तरीके से hoist नहीं करते हैं। और countdown फंक्शन है जबकि countdown() इसका परिणाम है, एक अंतर जो कम मायने रखता है जब आप फंक्शन को वैल्यूज के रूप में पास करना शुरू करते हैं।

पैरामीटर और रिटर्न वैल्यूज

एक फंक्शन तब अधिक उपयोगी होता है जब आप इसे कुछ दे सकते हैं। जिन वैल्यूज को आप देते हैं वे पैरामीटर होते हैं: नाम जो कोष्ठक में सूचीबद्ध होते हैं जो इसके लिए खड़े होते हैं जो आप इसे कॉल करते समय पास करते हैं।

js
function greet(name) {
  console.log("Hi " + name);
}

greet("Sam"); // Hi Sam
greet("Priya"); // Hi Priya

name पैरामीटर है। जब आप greet("Sam") कॉल करते हैं, तो पाठ "Sam" उस रन के लिए name में स्लॉट करता है। एक फंक्शन, विभिन्न परिणाम, इस पर निर्भर करता है कि आप इसे क्या देते हैं।

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

js
function double(number) {
  return number * 2;
}

const result = double(5);
console.log(result); // 10

return एक वैल्यू को फंक्शन से बाहर भेजता है। double(5) 10 बन जाता है, और आप इसे स्टोर कर सकते हैं, प्रिंट कर सकते हैं, या आगे पास कर सकते हैं। प्रिंटिंग स्क्रीन पर एक वैल्यू दिखाता है; रिटर्निंग इसे आपके कोड को वापस देता है ताकि आप इसे उपयोग करते रहें।

फंक्शन पैरामीटर के माध्यम से इनपुट लेते हैं: कोष्ठक में नाम। कॉल साइट पर जो वैल्यूज आप पास करते हैं वे arguments हैं जो उन्हें भरते हैं।

js
function priceWithTax(price, rate) {
  return price + price * rate;
}

const total = priceWithTax(40, 0.2);
console.log(total); // 48

price और rate पैरामीटर हैं; 40 और 0.2 इस कॉल के लिए arguments हैं। return statement जो कॉल करता है उसे एक वैल्यू वापस देता है, इसलिए priceWithTax(40, 0.2) 48 का मूल्यांकन करता है और आप इसे total में स्टोर कर सकते हैं।

लॉगिंग और रिटर्निंग के बीच का अंतर पिन करने योग्य है। एक फंक्शन जो console.log को कॉल करता है वह आपको कुछ दिखाता है और undefined का मूल्यांकन करता है; एक फंक्शन जो return का उपयोग करता है वह एक वैल्यू बनाता है जिसे आपका प्रोग्राम काम करता रहता है। return भी तुरंत फंक्शन को समाप्त करता है: इसके बाद की कोई भी लाइन नहीं चलती है। यदि आप return को बिल्कुल छोड़ देते हैं, तो फंक्शन अभी भी undefined रिटर्न करता है, जो एक सामान्य आश्चर्य है जब आप एक वैल्यू की उम्मीद करते हैं और कुछ नहीं पाते हैं।

पैरामीटर फंक्शन के नामित इनपुट हैं; arguments कंक्रीट वैल्यूज हैं जो कॉल साइट पर उन्हें बाध्य करते हैं। return statement फंक्शन की आउटपुट वैल्यू बनाता है और तुरंत execution को समाप्त करता है, इसलिए यह एक प्रारंभिक exit के रूप में दोहरा है:

js
function classify(score) {
  if (score < 0) {
    return "invalid";
  }
  if (score >= 60) {
    return "pass";
  }
  return "fail";
}

console.log(classify(72)); // pass
console.log(classify(-3)); // invalid

प्रत्येक return एक वैल्यू दोनों को प्राप्त करता है और फंक्शन को रोकता है, इसलिए एक बार एक शाखा fires हो, इसके नीचे कुछ नहीं चलता है। यह प्रारंभिक-exit पैटर्न (validate और पहले बेल करें, मुख्य case अंतिम हैंडल करें) आपको deeply nested conditionals से बाहर रखता है।

जो अंतर वास्तविक कोड में महत्वपूर्ण है वह एक फंक्शन के बीच है जो रिटर्न करता है और एक जो केवल एक side effect (कंसोल में लिखना, अपने आप को बदलना) बनाता है। console.log एक side effect प्रदर्शन करता है और फंक्शन undefined का मूल्यांकन करता है; return एक वैल्यू बनाता है जो caller compose कर सकता है। कोई return नहीं, या कुछ नहीं के बाद एक बेयर return, undefined yiels। एक फंक्शन से रिटर्न की गई वैल्यू के लिए पहुंचना जो केवल logs है एक लगातार bug है, और fix लगभग हमेशा वैल्यू को return करना है और इसे कॉल साइट पर लॉग करना है।

Junoपैरामीटर और रिटर्न वैल्यूज पैरामीटर कोष्ठक में नाम हैं जो आप आपने द्वारा पास की गई वैल्यूज के लिए खड़े होते हैं, इसलिए एक फंक्शन विभिन्न परिणाम दे सकता है। return एक वैल्यू को वापस देता है ताकि आपका कोड इसे बाद में उपयोग कर सके। console.log के साथ प्रिंटिंग इसे स्क्रीन पर दिखाता है; रिटर्निंग इसे आपको वापस देता है। मुझे यह अंतर महसूस करने में थोड़ा समय लगा।
Junoपैरामीटर और रिटर्न वैल्यूज पैरामीटर परिभाषा में नाम हैं, arguments कॉल पर आप पास की गई वैल्यूज हैं। return एक वैल्यू को caller को देता है और फंक्शन को तुरंत समाप्त करता है। एक फंक्शन जो केवल logs undefined का मूल्यांकन करता है, इसलिए यदि आप एक वैल्यू की उम्मीद करते हैं और कुछ नहीं मिला, तो जांचें कि क्या आपने वास्तव में इसे रिटर्न किया।
Junoपैरामीटर और रिटर्न वैल्यूजreturn एक वैल्यू और exits देता है, जो validate-and-bail-early को एक साफ पैटर्न बनाता है। रिटर्निंग एक वैल्यू और console.log जैसे side effect करने के बीच विभाजन देखें: लॉगिंग फंक्शन undefined का मूल्यांकन करता है। जब आप एक परिणाम के लिए पहुंचते हैं और कुछ नहीं पाते हैं, तो आपने लगभग हमेशा वह लॉग किया है जहां आप रिटर्न करने के लिए मतलब था।

Arrow फंक्शन

एक फंक्शन लिखने का एक छोटा तरीका है, जिसे arrow फंक्शन कहा जाता है। आप इसे एक वेरिएबल में स्टोर करते हैं और function कीवर्ड के बजाय => arrow का उपयोग करते हैं:

js
const add = (a, b) => {
  return a + b;
};

console.log(add(2, 3)); // 5

जब फंक्शन इस तरह एक single expression है, तो आप braces और return को ड्रॉप कर सकते हैं और arrow को वैल्यू को आपके लिए वापस करने देते हैं:

js
const add = (a, b) => a + b;

console.log(add(2, 3)); // 5

दोनों एक ही चीज करते हैं। आप modern JavaScript में हर जगह arrow फंक्शन देखेंगे, इसलिए आकार को पहचानना मदद करता है: एक नाम, एक =, inputs, एक arrow, और body।

एक arrow फंक्शन एक फंक्शन लिखने के लिए एक छोटा सिंटैक्स है, => के साथ एक वेरिएबल में स्टोर किया गया है:

js
const formatPrice = (amount) => `$${amount.toFixed(2)}`;

console.log(formatPrice(9.5)); // $9.50

जब body एक single expression है, arrow फंक्शन के पास implicit return है: कोई braces नहीं, कोई return कीवर्ड नहीं, expression की वैल्यू स्वचालित रूप से वापस कर दी जाती है। Braces जोड़ें और यह एक सामान्य फंक्शन body की तरह व्यवहार करता है, जहां आप return को अपने आप लिखते हैं:

js
const formatPrice = (amount) => {
  const rounded = amount.toFixed(2);
  return `$${rounded}`;
};

Arrows छोटे, single-purpose फंक्शन के लिए idiomatic पसंद हैं, विशेष रूप से छोटे जो आप अन्य फंक्शन को पास करते हैं (आप उन्हें array methods से मिलेंगे)। एक top-level, reusable, नामित routine के लिए, एक नियमित function घोषणा स्पष्ट रूप से पढ़ता है और अच्छी तरह काम करता है। Arrows के लिए पहुंचें जब संक्षिप्तता मदद करे और फंक्शन छोटा हो।

एक arrow फंक्शन => के साथ लिखा गया एक compact फंक्शन expression है। एक single-expression body के साथ यह एक implicit return है (expression की वैल्यू कोई return कीवर्ड के साथ रिटर्न की जाती है); एक braced body के साथ आप explicitly रिटर्न करते हैं, बिल्कुल एक regular फंक्शन की तरह।

js
const applyDiscount = (price, percent) => price * (1 - percent / 100);

console.log(applyDiscount(80, 25)); // 60

फंक्शन को परिभाषित करने के तीन तरीके coexist करते हैं, और अंतर cosmetic नहीं हैं, practical हैं:

  • एक फंक्शन घोषणा (function total() {}) hoisted है, इसलिए यह अपनी परिभाषा के ऊपर कॉल करने योग्य है।
  • एक फंक्शन expression (const total = function () {}) समान तरीके से hoisted नहीं है: वेरिएबल मौजूद है लेकिन जब तक लाइन चलती है तब तक undefined को hold करता है, इसलिए इसे पहले कॉल करने से error आता है।
  • एक arrow फंक्शन (const total = () => {}) hoisting के लिए एक expression की तरह व्यवहार करता है और एक key नियम नीचे जोड़ता है।

जो नियम arrows को अलग करता है: वे अपने स्वयं के this को bind नहीं करते हैं। एक regular फंक्शन को एक this मिलता है जो यह कॉल किया जाता है; एक arrow घिरे हुए कोड से this को inherit करता है। यह अंतर तब तक काटता नहीं जब तक आप objects पर methods लिख रहे हों, इसलिए तथ्य को hold करें और reasoning वहां lands है।

दो और tools worth उपयोग करने। Default parameters एक fallback देता है जब एक argument missing हो, इसलिए फंक्शन predictable रहता है:

js
const greet = (name = "there") => `Hi ${name}`;

console.log(greet("Sam")); // Hi Sam
console.log(greet()); // Hi there

और आदत जो सबसे अधिक payoff करती है: pure फंक्शन को prefer करें, ones जिनकी आउटपुट केवल उनके inputs पर निर्भर करती है और जो अपने आप को कुछ नहीं बदलते (कोई side effects नहीं)। ऊपर applyDiscount pure है: same inputs, same result, हर बार। Pure फंक्शन वह हैं जिन्हें आप isolation में test कर सकते हैं, प्रोग्राम के बाकी को ट्रेस किए बिना reasoning कर सकते हैं, और surprises के बिना फिर से उपयोग कर सकते हैं। सब कुछ pure नहीं हो सकता है (कुछ को log, fetch, और state बदलना है), लेकिन आपके logic को pure फंक्शन में pushing करना और side effects को edges पर रखना language में सबसे highest-leverage आदत में से एक है।

JunoArrow फंक्शन एक arrow फंक्शन एक फंक्शन लिखने का एक छोटा तरीका है, function कीवर्ड के बजाय => के साथ एक वेरिएबल में स्टोर किया गया है। जब body एक expression है, तो आप braces और return को ड्रॉप कर सकते हैं और arrow आपके लिए वैल्यू को वापस देता है। आप इस आकार को लगातार देखेंगे, इसलिए इसे पढ़ने में comfortable हो जाना जल्दी payoff करता है।
JunoArrow फंक्शन Arrows फंक्शन के लिए short form हैं, और एक single-expression body आपको एक implicit return देता है: कोई braces नहीं, कोई return। Braces जोड़ें और आप return को normal की तरह अपने आप लिखते हैं। छोटे, single-purpose फंक्शन पर arrows के लिए पहुंचें; एक plain function घोषणा अभी भी एक top-level नामित routine के लिए great पढ़ता है।
JunoArrow फंक्शन Declarations hoist करते हैं, expressions और arrows नहीं करते हैं, और arrows भी अपने स्वयं के this को skip करते हैं, जो केवल मायने रखता है एक बार जब आप object methods लिखते हैं। Missing arguments के लिए default parameters पर lean करें, और अपने logic को pure फंक्शन में push करें जिनकी आउटपुट केवल उनके inputs पर निर्भर करती है। वह ones हैं जिन्हें आप अकेले test कर सकते हैं और पूरे प्रोग्राम को ट्रेस किए बिना फिर से उपयोग कर सकते हैं।

फंक्शन यहां से कहां जाते हैं

फंक्शन आप अपने आप को repeat करना बंद कर देते हैं: चरणों के एक ब्लॉक को नाम दें, इसे inputs दें, एक वैल्यू वापस पाएं। एक बार यह clicks, अधिकांश कोड जो आप लिखते हैं छोटे फंक्शन अन्य फंक्शन को कॉल करने हो जाते हैं, प्रत्येक एक स्पष्ट job करते हैं।

यहां से, फंक्शन हर जगह दिखते हैं। आप उन्हें array methods को पास करेंगे ताकि data की सूची को transform कर सकें, उन्हें conditionals से branching logic को organize करने के लिए उपयोग करेंगे, और variables के साथ शुरू किए गए naming discipline पर lean करेंगे। अगली बार जब आप अपने आप को कोड के एक ब्लॉक को कॉपी करते हुए पकड़ते हैं, तो यह एक फंक्शन में इसे wrap करने का signal है।