यहां मानक रूपों पर रंडन है जो कार्य बनाते हैं: (मूल रूप से एक और प्रश्न के लिए लिखा गया है, लेकिन विहित प्रश्न में स्थानांतरित होने के बाद अनुकूलित किया गया है।)
शर्तें:
त्वरित सूची:
समारोह घोषणा
"बेनामी" function
अभिव्यक्ति (जो शब्द के बावजूद, कभी-कभी नामों के साथ फ़ंक्शन बनाते हैं)
जिसका नाम function
अभिव्यक्ति है
एक्सेसर फंक्शन इनिशियलाइज़र (ES5 +)
एरो फंक्शन एक्सप्रेशन (ES2015 +) (जो अनाम फ़ंक्शन एक्सप्रेशन की तरह है, इसमें स्पष्ट नाम शामिल नहीं है, और फिर भी नाम के साथ बना सकते हैं)
विधि आरंभक में विधि घोषणा (ES2015 +)
class
(ES2015 +) में कंस्ट्रक्टर और विधि घोषणाएँ
समारोह घोषणा
पहला रूप एक फ़ंक्शन घोषणा है , जो इस तरह दिखता है:
function x() {
console.log('x');
}
एक फ़ंक्शन घोषणा एक घोषणा है ; यह एक बयान या अभिव्यक्ति नहीं है। जैसे, आप इसका पालन नहीं करते हैं ;
(हालांकि ऐसा करना हानिरहित है)।
एक फ़ंक्शन घोषणा को संसाधित किया जाता है जब निष्पादन उस संदर्भ में प्रवेश करता है जिसमें यह दिखाई देता है, इससे पहले कि कोई भी चरण-दर-चरण कोड निष्पादित हो। इसे बनाने वाले फ़ंक्शन को एक उचित नाम दिया गया है (x
ऊपर उदाहरण में), और उस नाम को उस दायरे में रखा जाता है जिसमें घोषणा प्रकट होती है।
क्योंकि यह एक ही संदर्भ में किसी भी चरण-दर-चरण कोड से पहले संसाधित होता है, आप इस तरह की चीजें कर सकते हैं:
x(); // Works even though it's above the declaration
function x() {
console.log('x');
}
ES2015 तक, कल्पना को कवर नहीं किया है जो एक JavaScript इंजन अगर आप की तरह एक नियंत्रण संरचना के अंदर एक समारोह घोषणा डाल करना चाहिए try
, if
, switch
, while
इस तरह, आदि:
if (someCondition) {
function foo() { // <===== HERE THERE
} // <===== BE DRAGONS
}
और जब से वे चरण-दर-चरण कोड चलने से पहले संसाधित होते हैं , यह जानना मुश्किल है कि जब वे नियंत्रण संरचना में होते हैं तो क्या करना है।
हालांकि ऐसा करने को ES2015 तक निर्दिष्ट नहीं किया गया था, यह ब्लॉकों में फ़ंक्शन घोषणाओं का समर्थन करने के लिए एक स्वीकार्य विस्तार था । दुर्भाग्य से (और अनिवार्य रूप से), अलग-अलग इंजनों ने अलग-अलग चीजें कीं।
ES2015 के अनुसार, विनिर्देश कहता है कि क्या करना है। वास्तव में, यह करने के लिए तीन अलग-अलग चीजें देता है:
- यदि वेब ब्राउजर पर ढीले मोड में नहीं है, तो जावास्क्रिप्ट इंजन को एक काम करना चाहिए
- यदि वेब ब्राउज़र पर ढीले मोड में, जावास्क्रिप्ट इंजन को कुछ और करना चाहिए
- यदि सख्त मोड (ब्राउज़र या नहीं) में, जावास्क्रिप्ट इंजन को अभी एक और काम करना है
ढीले मोड के लिए नियम मुश्किल हैं, लेकिन सख्त मोड में, ब्लॉक में फ़ंक्शन घोषणाएं आसान हैं: वे ब्लॉक के लिए स्थानीय हैं (उनके पास ब्लॉक गुंजाइश है , जो ES2015 में भी नया है), और वे शीर्ष पर फहराए गए हैं ब्लॉक के। इसलिए:
"use strict";
if (someCondition) {
foo(); // Works just fine
function foo() {
}
}
console.log(typeof foo); // "undefined" (`foo` is not in scope here
// because it's not in the same block)
"अनाम" function
अभिव्यक्ति
दूसरे सामान्य रूप को एक अनाम फ़ंक्शन एक्सप्रेशन कहा जाता है :
var y = function () {
console.log('y');
};
सभी अभिव्यक्तियों की तरह, इसका मूल्यांकन तब किया जाता है जब यह कोड के चरण-दर-चरण निष्पादन में पहुंच जाता है।
ES5 में, यह जो फ़ंक्शन बनाता है उसका कोई नाम नहीं है (यह अनाम है)। ES2015 में, फ़ंक्शन को संदर्भ से संदर्भित करके यदि संभव हो तो एक नाम सौंपा गया है। ऊपर के उदाहरण में, नाम होगा y
। कुछ ऐसा ही किया जाता है जब फ़ंक्शन एक संपत्ति इनिशियलाइज़र का मूल्य होता है। (ऐसा कब होता है और नियमों पर विवरण के SetFunctionName
लिए , विनिर्देश में खोजें - यह सभी जगह दिखाई देता है।)
जिसका नाम function
अभिव्यक्ति है
तीसरा रूप एक नामित फ़ंक्शन अभिव्यक्ति ("NFE") है:
var z = function w() {
console.log('zw')
};
यह जो फ़ंक्शन बनाता है उसका एक उचित नाम ( w
इस मामले में) है। सभी अभिव्यक्तियों की तरह, इसका मूल्यांकन कोड के चरण-दर-चरण निष्पादन में पहुंचने पर किया जाता है। फ़ंक्शन का नाम उस दायरे में नहीं जोड़ा जाता है जिसमें अभिव्यक्ति दिखाई देती है; नाम है समारोह के भीतर ही दायरे में:
var z = function w() {
console.log(typeof w); // "function"
};
console.log(typeof w); // "undefined"
ध्यान दें कि NFE अक्सर जावास्क्रिप्ट कार्यान्वयन के लिए बग का स्रोत रहा है। IE8 और पहले, उदाहरण के लिए, NFE को पूरी तरह से गलत तरीके से संभालते हैं , जिससे दो अलग-अलग समय पर दो अलग-अलग कार्य होते हैं। सफारी के शुरुआती संस्करणों में भी मुद्दे थे। अच्छी खबर यह है कि ब्राउज़रों के वर्तमान संस्करण (IE9 और ऊपर, वर्तमान सफारी) में कोई समस्या नहीं है। (लेकिन इस लेखन के रूप में, दुख की बात है, IE8 व्यापक उपयोग में रहता है, और इसलिए सामान्य रूप से वेब के लिए कोड के साथ NFE का उपयोग करना अभी भी समस्याग्रस्त है।)
एक्सेसर फंक्शन इनिशियलाइज़र (ES5 +)
कभी-कभी फ़ंक्शंस मोटे तौर पर किसी का ध्यान नहीं खींच सकते हैं; एक्सेसर कार्यों के साथ ऐसा ही है । यहाँ एक उदाहरण है:
var obj = {
value: 0,
get f() {
return this.value;
},
set f(v) {
this.value = v;
}
};
console.log(obj.f); // 0
console.log(typeof obj.f); // "number"
ध्यान दें कि जब मैंने फ़ंक्शन का उपयोग किया, तो मैंने उपयोग नहीं किया ()
! ऐसा इसलिए है क्योंकि यह एक संपत्ति के लिए एक गौण कार्य है । हम संपत्ति को सामान्य तरीके से प्राप्त करते हैं और सेट करते हैं, लेकिन पर्दे के पीछे, फ़ंक्शन को कहा जाता है।
तुम भी साथ एक्सेसर कार्यों बना सकते हैं Object.defineProperty
, Object.defineProperties
और करने के लिए कम प्रसिद्ध दूसरा तर्क Object.create
।
एरो फंक्शन एक्सप्रेशन (ES2015 +)
ES2015 हमें एरो फंक्शन लाता है । यहाँ एक उदाहरण है:
var a = [1, 2, 3];
var b = a.map(n => n * 2);
console.log(b.join(", ")); // 2, 4, 6
कॉल n => n * 2
में छुपाने वाली चीज़ देखें map()
? यह एक समारोह है।
तीर के कार्यों के बारे में कुछ बातें:
उनके पास अपना नहीं है this
। इसके बजाय, वे पास के ऊपरthis
संदर्भ में, जहां वे परिभाषित कर रहे हैं। (वे भी बंद कर देते हैं arguments
और, जहां प्रासंगिक है super
।) इसका मतलब है कि उनके this
भीतर वही है this
जहां वे बनाए गए हैं, और बदला नहीं जा सकता।
जैसा कि आपने ऊपर देखा है, आप कीवर्ड का उपयोग नहीं करते हैं function
; इसके बजाय, आप का उपयोग करें =>
।
n => n * 2
उपरोक्त उदाहरण उनमें से एक रूप है। यदि फ़ंक्शन को पास करने के लिए आपके पास कई तर्क हैं, तो आप parens का उपयोग करते हैं:
var a = [1, 2, 3];
var b = a.map((n, i) => n * i);
console.log(b.join(", ")); // 0, 2, 6
(याद रखें कि Array#map
प्रविष्टि को पहले तर्क के रूप में और दूसरे के रूप में सूचकांक को पास करें।)
दोनों मामलों में, फ़ंक्शन का शरीर केवल एक अभिव्यक्ति है; फ़ंक्शन का रिटर्न मान स्वचालित रूप से उस अभिव्यक्ति का परिणाम होगा (आप एक स्पष्ट उपयोग नहीं करते हैं return
)।
यदि आप सामान्य से अधिक एकल अभिव्यक्ति, उपयोग {}
और एक स्पष्ट return
(यदि आपको कोई मूल्य वापस करने की आवश्यकता है) कर रहे हैं, तो सामान्य:
var a = [
{first: "Joe", last: "Bloggs"},
{first: "Albert", last: "Bloggs"},
{first: "Mary", last: "Albright"}
];
a = a.sort((a, b) => {
var rv = a.last.localeCompare(b.last);
if (rv === 0) {
rv = a.first.localeCompare(b.first);
}
return rv;
});
console.log(JSON.stringify(a));
बिना संस्करण को एक्सप्रेशन बॉडी या संक्षिप्त बॉडी{ ... }
वाला एरो फंक्शन कहा जाता है । (यह भी: एक संक्षिप्त तीर फ़ंक्शन।) शरीर को परिभाषित करने वाला एक फ़ंक्शन फ़ंक्शन के साथ एक तीर फ़ंक्शन है । (इसके अलावा: एक वर्बोज़ तीर कार्य करते हैं।){ ... }
विधि आरंभक में विधि घोषणा (ES2015 +)
ES2015 एक संपत्ति घोषित करने के एक छोटे रूप की अनुमति देता है जो एक फ़ंक्शन को संदर्भित करता है जिसे विधि परिभाषा कहा जाता है ; यह इस तरह दिख रहा है:
var o = {
foo() {
}
};
ES5 में लगभग बराबर और पहले होगा:
var o = {
foo: function foo() {
}
};
अंतर ( super
क्रिया के अलावा) यह है कि एक विधि का उपयोग कर सकते हैं , लेकिन एक समारोह नहीं कर सकते। उदाहरण के लिए, यदि आपके पास कोई ऐसी वस्तु है जो valueOf
विधि सिंटैक्स का उपयोग करते हुए परिभाषित (कहती है) करती है , तो super.valueOf()
वह मान प्राप्त करने के लिए उपयोग कर सकता है Object.prototype.valueOf
(संभवतः इसके साथ कुछ और करने से पहले), जबकि ES5 संस्करण को इसके Object.prototype.valueOf.call(this)
बजाय करना होगा।
इसका मतलब यह भी है कि विधि में उस वस्तु का संदर्भ है जिस पर इसे परिभाषित किया गया था, इसलिए यदि वह वस्तु अस्थायी है (उदाहरण के लिए, आप इसे Object.assign
स्रोत ऑब्जेक्ट में से एक के रूप में पारित कर रहे हैं), तो विधि सिंटैक्स का अर्थ हो सकता है कि ऑब्जेक्ट बरकरार है स्मृति में जब अन्यथा यह कचरा एकत्र किया जा सकता था (यदि जावास्क्रिप्ट इंजन उस स्थिति का पता नहीं लगाता है और यदि कोई भी विधि उपयोग नहीं करता है तो इसे संभाल लें super
)।
class
(ES2015 +) में कंस्ट्रक्टर और विधि घोषणाएँ
ES2015 हमें class
घोषित रचनाकारों और विधियों सहित सिंटैक्स लाता है :
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
getFullName() {
return this.firstName + " " + this.lastName;
}
}
ऊपर दो फ़ंक्शन घोषणाएं हैं: एक कंस्ट्रक्टर के लिए, जिसे नाम मिलता है Person
, और एक के लिए getFullName
, जो एक फ़ंक्शन को सौंपा गया है Person.prototype
।