var फ़ंक्शन नाम = फ़ंक्शन () {} बनाम फ़ंक्शन फ़ंक्शन नाम () {}


6871

मैंने हाल ही में किसी और के जावास्क्रिप्ट कोड को बनाए रखना शुरू किया है। मैं बग को ठीक कर रहा हूं, सुविधाओं को जोड़ रहा हूं और कोड को साफ करने और इसे अधिक सुसंगत बनाने की कोशिश कर रहा हूं।

पिछले डेवलपर ने फ़ंक्शंस घोषित करने के दो तरीकों का इस्तेमाल किया था और अगर इसके पीछे कोई कारण है या नहीं तो मैं काम नहीं कर सकता।

दो तरीके हैं:

var functionOne = function() {
    // Some code
};
function functionTwo() {
    // Some code
}

इन दो अलग-अलग तरीकों का उपयोग करने के कारण क्या हैं और प्रत्येक के पेशेवरों और विपक्ष क्या हैं? क्या ऐसा कुछ है जो एक विधि से किया जा सकता है जो दूसरे के साथ नहीं किया जा सकता है?


198
permadi.com/tutorial/jsFunc/index.html जावास्क्रिप्ट फ़ंक्शंस के बारे में बहुत अच्छा पेज है
uzay95

67
संबंधित नामांकित समारोह अभिव्यक्ति पर यह उत्कृष्ट लेख है ।
फ्रॉग्ज

12
@CMS संदर्भ इस लेख: kangax.github.com/nfe/#expr-vs-decl
Upperstage

106
दो चीजों से आपको अवगत होना चाहिए: # 1 जावास्क्रिप्ट में, घोषणाएं फहराई जाती हैं। मतलब जो var a = 1; var b = 2;बन जाता है var a; var b; a = 1; b = 2। इसलिए जब आप functionOne घोषित करते हैं, तो यह घोषित हो जाता है, लेकिन इसका मान तुरंत सेट नहीं किया जाता है। जबकि functionTwo सिर्फ एक घोषणा है, यह गुंजाइश के शीर्ष पर रखा जाता है। # 2 functionTwo आपको नाम प्रॉपर्टी एक्सेस करने देता है और किसी चीज़ को डीबग करने की कोशिश में बहुत मदद करता है।
xavierm02

65
ओह और btw, सही वाक्यविन्यास एक "के साथ है?" असाइनमेंट के बाद और घोषणा के बिना। जैसे function f(){}बनाम var f = function(){};
xavierm02

जवाबों:


5042

अंतर यह है कि functionOneएक फ़ंक्शन अभिव्यक्ति है और इसलिए केवल उस रेखा तक पहुंचने पर परिभाषित किया गया है, जबकि functionTwoएक फ़ंक्शन घोषणा है और जैसे ही इसके आसपास के फ़ंक्शन या स्क्रिप्ट को निष्पादित किया जाता है ( उत्थापन के कारण ) को परिभाषित किया जाता है ।

उदाहरण के लिए, एक फ़ंक्शन अभिव्यक्ति:

// TypeError: functionOne is not a function
functionOne();

var functionOne = function() {
  console.log("Hello!");
};

और, एक फ़ंक्शन घोषणा:

// Outputs: "Hello!"
functionTwo();

function functionTwo() {
  console.log("Hello!");
}

ऐतिहासिक रूप से, ब्लॉक के भीतर परिभाषित फ़ंक्शन घोषणाओं को ब्राउज़र के बीच असंगत रूप से नियंत्रित किया गया था। सख्त मोड (ईएस 5 में पेश किया गया) ने उनके संलग्न ब्लॉक को फ़ंक्शन घोषणाओं को देखकर इसे हल किया।

'use strict';    
{ // note this block!
  function functionThree() {
    console.log("Hello!");
  }
}
functionThree(); // ReferenceError


631
@Greg: वैसे, अंतर केवल इतना नहीं है कि वे अलग-अलग समय पर पार्स किए जाते हैं। अनिवार्य रूप से, आपका functionOneकेवल एक चर है जिसे एक अनाम फ़ंक्शन दिया गया है, जबकि functionTwoवास्तव में एक नामित फ़ंक्शन है। .toString()अंतर देखने के लिए दोनों को कॉल करें । यह कुछ मामलों में महत्वपूर्ण है जहां आप प्रोग्राम के नाम को प्रोग्रामेटिक रूप से प्राप्त करना चाहते हैं।
जेसन बंटिंग

6
: @Jason गौरेया .. यकीन है कि क्या नहीं तुम यहाँ पर हो रही है, .toString () अनिवार्य रूप से दोनों के लिए एक ही मूल्य (समारोह परिभाषा) वापस जाने के लिए लगता है cl.ly/2a2C2Y1r0J451o0q0B1B
जॉन जेड

124
दोनों अलग हैं। पहला एक function expressionदूसरा है दूसरा एक है function declaration। आप इस विषय पर यहाँ और अधिक पढ़ सकते हैं: javascriptweblog.wordpress.com/2010/07/06/…
मीकल कुक्लिइस

127
@Greg बनाम रन समय के संबंध में आपके उत्तर का हिस्सा सही नहीं है। जावास्क्रिप्ट में, फ़ंक्शन घोषणाओं को पार्स समय के दौरान परिभाषित नहीं किया जाता है, लेकिन रन समय के दौरान। प्रक्रिया इस तरह से होती है: स्रोत कोड को पार्स किया जाता है -> जावास्क्रिप्ट प्रोग्राम का मूल्यांकन किया जाता है -> वैश्विक निष्पादन संदर्भ को आरंभीकृत किया जाता है -> घोषणा बाध्यकारी तात्कालिकता का प्रदर्शन किया जाता है। इस प्रक्रिया के दौरान फ़ंक्शन घोषणाओं को त्वरित किया जाता है ( अध्याय 10.5 के चरण 5 देखें )।
59इमे विद

102
इस घटना के लिए शब्दावली को उत्थापन के रूप में जाना जाता है।
कॉलिन पीयर

1941

पहले मैं ग्रेग को सही करना चाहता हूं: function abc(){}इसे भी बंद कर दिया गया है - नाम abcउस दायरे में परिभाषित किया गया है जहां इस परिभाषा का सामना किया गया है। उदाहरण:

function xyz(){
  function abc(){};
  // abc is defined here...
}
// ...but not here

दूसरे, दोनों शैलियों को जोड़ना संभव है:

var xyz = function abc(){};

xyzहमेशा की तरह परिभाषित किया जा रहा है, abcसभी ब्राउज़रों में अपरिभाषित है लेकिन इंटरनेट एक्सप्लोरर - परिभाषित होने पर भरोसा नहीं करता है। लेकिन इसे इसके शरीर के अंदर परिभाषित किया जाएगा:

var xyz = function abc(){
  // xyz is visible here
  // abc is visible here
}
// xyz is visible here
// abc is undefined here

यदि आप सभी ब्राउज़रों पर कार्य करना चाहते हैं, तो इस तरह की घोषणा का उपयोग करें:

function abc(){};
var xyz = abc;

इस मामले में, दोनों xyzऔर abcएक ही वस्तु के उपनाम हैं:

console.log(xyz === abc); // prints "true"

संयुक्त शैली का उपयोग करने के लिए एक सम्मोहक कारण फ़ंक्शन ऑब्जेक्ट्स का "नाम" विशेषता है ( इंटरनेट एक्सप्लोरर द्वारा समर्थित नहीं है )। असल में जब आप किसी फ़ंक्शन को परिभाषित करते हैं

function abc(){};
console.log(abc.name); // prints "abc"

इसका नाम स्वचालित रूप से असाइन किया गया है। लेकिन जब आप इसे परिभाषित करते हैं

var abc = function(){};
console.log(abc.name); // prints ""

इसका नाम रिक्त है - हमने एक अनाम फ़ंक्शन बनाया और इसे कुछ चर में सौंपा।

संयुक्त शैली का उपयोग करने का एक और अच्छा कारण बाहरी उपयोगकर्ताओं के लिए एक लंबा गैर-परस्पर विरोधी नाम प्रदान करते हुए, अपने आप को संदर्भित करने के लिए एक छोटे आंतरिक नाम का उपयोग करना है:

// Assume really.long.external.scoped is {}
really.long.external.scoped.name = function shortcut(n){
  // Let it call itself recursively:
  shortcut(n - 1);
  // ...
  // Let it pass itself as a callback:
  someFunction(shortcut);
  // ...
}

ऊपर दिए गए उदाहरण में हम बाहरी नाम के साथ भी ऐसा कर सकते हैं, लेकिन यह बहुत ही अस्पष्ट (और धीमा) होगा।

(खुद को संदर्भित करने का दूसरा तरीका उपयोग करना है arguments.callee, जो अभी भी अपेक्षाकृत लंबा है, और सख्त मोड में समर्थित नहीं है।)

नीचे दीप, जावास्क्रिप्ट दोनों बयानों को अलग तरह से व्यवहार करता है। यह एक फ़ंक्शन घोषणा है:

function abc(){}

abc यहाँ वर्तमान दायरे में हर जगह परिभाषित किया गया है:

// We can call it here
abc(); // Works

// Yet, it is defined down there.
function abc(){}

// We can call it again
abc(); // Works

इसके अलावा, यह एक returnबयान के माध्यम से फहराया गया :

// We can call it here
abc(); // Works
return;
function abc(){}

यह एक फ़ंक्शन अभिव्यक्ति है:

var xyz = function(){};

xyz यहाँ असाइनमेंट के बिंदु से परिभाषित किया गया है:

// We can't call it here
xyz(); // UNDEFINED!!!

// Now it is defined
xyz = function(){}

// We can call it here
xyz(); // works

फंक्शन की घोषणा बनाम फ़ंक्शन अभिव्यक्ति वास्तविक कारण है जिसके कारण ग्रेग द्वारा प्रदर्शित अंतर है।

मजेदार तथ्य:

var xyz = function abc(){};
console.log(xyz.name); // Prints "abc"

व्यक्तिगत रूप से, मैं "फ़ंक्शन एक्सप्रेशन" घोषणा को पसंद करता हूं क्योंकि इस तरह से मैं दृश्यता को नियंत्रित कर सकता हूं। जब मैं फ़ंक्शन को परिभाषित करता हूं

var abc = function(){};

मुझे पता है कि मैंने समारोह को स्थानीय रूप से परिभाषित किया है। जब मैं फ़ंक्शन को परिभाषित करता हूं

abc = function(){};

मुझे पता है कि मैंने इसे विश्व स्तर पर परिभाषित किया कि मैं abcकहीं भी स्कोप की श्रृंखला में परिभाषित नहीं करता । परिभाषा की यह शैली अंदर उपयोग किए जाने पर भी लचीला है eval()। जबकि परिभाषा है

function abc(){};

संदर्भ पर निर्भर करता है और आपको यह अनुमान लगाना छोड़ सकता है कि यह वास्तव में कहां परिभाषित किया गया है, विशेष रूप से इस मामले में eval()- उत्तर है: यह ब्राउज़र पर निर्भर करता है।


69
मैं RoBorg का संदर्भ देता हूं लेकिन वह कहीं नहीं है। सरल: RoBorg === ग्रेग। यही कारण है कि इंटरनेट के युग में इतिहास को फिर से लिखा जा सकता है। ;-)
यूजीन लैजुटकिन 2

10
var xyz = function abc () {}; कंसोल.लॉग (xyz === abc); मेरे द्वारा परीक्षण किए गए सभी ब्राउज़र (सफारी 4, फ़ायरफ़ॉक्स 3.5.5, ओपेरा 10.10) मुझे "अपरिभाषित चर: एबीसी" देता है।
एनवीआई

7
कुल मिलाकर मुझे लगता है कि यह पोस्ट फंक्शन डिक्लेरेशन के उपयोग के अंतर और फायदों के बारे में बताने का अच्छा काम करता है। जहाँ तक विशेष रूप से "लाभ" एक वैश्विक संस्था घोषित करने की सलाह के रूप में लगता है कि एक चर के लिए फ़ंक्शन अभिव्यक्ति असाइनमेंट का उपयोग करने के लाभों के रूप में सहमत नहीं हूँ ... और हर कोई जानता है कि आपको वैश्विक नाम स्थान अव्यवस्थित नहीं करना चाहिए , सही? ;-)
natlee75

83
नामांकित फ़ंक्शन का उपयोग करने का एक बहुत बड़ा कारण यह है कि डीबगर आपके कॉल स्टैक या स्टैक ट्रेस की समझ बनाने में मदद करने के लिए नाम का उपयोग कर सकते हैं। यह तब होता है जब आप कॉल स्टैक को देखते हैं और "अनाम फ़ंक्शन" को 10 स्तरों तक देखते हैं ...
बकरी

3
var abc = function(){}; console.log(abc.name);""कोई और उत्पादन नहीं करता है , बल्कि "abc"इसके बजाय।
क्वर्टी

632

यहां मानक रूपों पर रंडन है जो कार्य बनाते हैं: (मूल रूप से एक और प्रश्न के लिए लिखा गया है, लेकिन विहित प्रश्न में स्थानांतरित होने के बाद अनुकूलित किया गया है।)

शर्तें:

त्वरित सूची:

  • समारोह घोषणा

  • "बेनामी" 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 के अनुसार, विनिर्देश कहता है कि क्या करना है। वास्तव में, यह करने के लिए तीन अलग-अलग चीजें देता है:

  1. यदि वेब ब्राउजर पर ढीले मोड में नहीं है, तो जावास्क्रिप्ट इंजन को एक काम करना चाहिए
  2. यदि वेब ब्राउज़र पर ढीले मोड में, जावास्क्रिप्ट इंजन को कुछ और करना चाहिए
  3. यदि सख्त मोड (ब्राउज़र या नहीं) में, जावास्क्रिप्ट इंजन को अभी एक और काम करना है

ढीले मोड के लिए नियम मुश्किल हैं, लेकिन सख्त मोड में, ब्लॉक में फ़ंक्शन घोषणाएं आसान हैं: वे ब्लॉक के लिए स्थानीय हैं (उनके पास ब्लॉक गुंजाइश है , जो 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()? यह एक समारोह है।

तीर के कार्यों के बारे में कुछ बातें:

  1. उनके पास अपना नहीं है this। इसके बजाय, वे पास के ऊपरthis संदर्भ में, जहां वे परिभाषित कर रहे हैं। (वे भी बंद कर देते हैं argumentsऔर, जहां प्रासंगिक है super।) इसका मतलब है कि उनके thisभीतर वही है thisजहां वे बनाए गए हैं, और बदला नहीं जा सकता।

  2. जैसा कि आपने ऊपर देखा है, आप कीवर्ड का उपयोग नहीं करते हैं 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


3
फिर नाम wको केवल अनदेखा कर दिया जाता है?
BiAiB

8
@PellePenna: फ़ंक्शन नाम बहुत सारी चीजों के लिए उपयोगी हैं। मेरे विचार में दो दिग्गजों की पुनरावृत्ति है, और फ़ंक्शन का नाम कॉल स्टैक्स, अपवाद निशान, और ऐसे में दिखाया जा रहा है।
TJ क्राउडर

4
@ChaimEliyah - "स्वीकार करने का मतलब यह नहीं है कि यह सबसे अच्छा जवाब है, इसका मतलब है कि यह उस व्यक्ति के लिए काम करता है जिसने पूछा है।" source
स्कै्रपकोड

6
@AR: काफी सच है। हालांकि, इसके ठीक ऊपर, यह कहता है कि "सबसे अच्छे उत्तर पहले दिखाई देते हैं ताकि वे हमेशा आसानी से मिल सकें।" चूँकि स्वीकृत उत्तर पहले से उच्चतर मतदान पर भी दिखाई देता है, इसलिए दौरा कुछ हद तक आत्मविरोधी हो सकता है। ;-) थोड़ा गलत भी है, अगर हम वोट द्वारा "सबसे अच्छा" निर्धारित करते हैं (जो विश्वसनीय नहीं है, यह वही है जो हमें मिला है), "सर्वश्रेष्ठ" उत्तर केवल पहले दिखाते हैं यदि आप "वोट" टैब का उपयोग कर रहे हैं - अन्यथा, उत्तर जो पहले सक्रिय हैं, या सबसे पुराने हैं।
टीजे क्राउडर

1
@TJCrowder: सहमत। sometimes तारीख से व्यवस्थित ’कभी-कभी कष्टप्रद होता है।
स्क्रेपकोड

143

वैश्विक संदर्भ के बारे में बोलते हुए, varकथन और FunctionDeclarationअंत में दोनों वैश्विक वस्तु पर एक गैर-हटाने योग्य संपत्ति बनाएंगे , लेकिन दोनों के मूल्य को अधिलेखित किया जा सकता है

दो तरीकों के बीच सूक्ष्म अंतर यह है कि जब परिवर्तनीय तात्कालिकता प्रक्रिया चलती है (वास्तविक कोड निष्पादन से पहले) के साथ घोषित सभी पहचानकर्ताओं के साथ varआरंभ किया जाएगा undefined, और FunctionDeclarationउस क्षण के बाद से उपयोग किए जाने वाले उपलब्ध होंगे, उदाहरण के लिए:

 alert(typeof foo); // 'function', it's already available
 alert(typeof bar); // 'undefined'
 function foo () {}
 var bar = function () {};
 alert(typeof bar); // 'function'

bar FunctionExpressionरनटाइम तक असाइनमेंट होता है।

एक वैश्विक संपत्ति FunctionDeclarationको किसी भी समस्या के बिना एक परिवर्तनीय मूल्य की तरह अधिलेखित किया जा सकता है, जैसे:

 function test () {}
 test = null;

आपके दो उदाहरणों के बीच एक और स्पष्ट अंतर यह है कि पहले फ़ंक्शन का कोई नाम नहीं है, लेकिन दूसरे में यह है, जो डिबगिंग (यानी कॉल स्टैक का निरीक्षण) करते समय वास्तव में उपयोगी हो सकता है।

आपके संपादित पहले उदाहरण ( foo = function() { alert('hello!'); };) के बारे में, यह एक अघोषित असाइनमेंट है, मैं आपको हमेशा varकीवर्ड का उपयोग करने के लिए प्रोत्साहित करता हूँ ।

एक असाइनमेंट के साथ, varबयान के बिना , यदि संदर्भित पहचानकर्ता गुंजाइश श्रृंखला में नहीं पाया जाता है, तो यह वैश्विक ऑब्जेक्ट की एक हटाने योग्य संपत्ति बन जाएगा ।

इसके अलावा, अघोषित असाइनमेंट सख्त मोड केReferenceError तहत ECMAScript 5 पर फेंकते हैं ।

एक अवश्य पढ़ने की बात:

नोट : इस उत्तर को एक अन्य प्रश्न से मर्ज किया गया है , जिसमें ओपी से प्रमुख संदेह और गलतफहमी थी कि एक के साथ घोषित किए गए पहचानकर्ताओं FunctionDeclarationको ओवरराइट किया जा सकता है जो कि मामला नहीं है।


मुझे नहीं पता था कि जावास्क्रिप्ट में कार्यों को अधिलेखित किया जा सकता है! इसके अलावा, वह पार्स ऑर्डर मेरे लिए बड़ा विक्रय बिंदु है। मुझे लगता है कि मुझे यह देखने की आवश्यकता है कि मैं कैसे कार्य करता हूं।
Xeoncross

2
"नाम समारोह अभिव्यक्ति को नष्ट कर दिया" के लिए +0 404ing के रूप में लेख। संभावित दर्पण ?: kangax.github.com/nfe
Mr_Chimp

@ सीएमएस अच्छा लगा। ध्यान रखें कि हालांकि मैंने मूल कभी नहीं देखा था, इसलिए मुझे नहीं पता कि यह एक दर्पण है या एक ही शीर्षक वाला कोई अन्य लेख है!
Mr_Chimp

@Mr_Chimp मुझे पूरा यकीन है कि, यह है कि, मार्गबैकमाइन कह रहा है कि इसे क्रॉल के समय 302 मिला और रीडायरेक्शन आपके द्वारा दिए गए लिंक पर था।
जॉन

123

लगभग सभी उद्देश्यों के लिए आपने जो दो कोड स्निपेट पोस्ट किए हैं, वे उसी तरह से व्यवहार करेंगे।

हालांकि, व्यवहार में अंतर यह है कि पहले संस्करण ( var functionOne = function() {}) के साथ, उस फ़ंक्शन को कोड में उस बिंदु के बाद ही बुलाया जा सकता है।

दूसरे संस्करण ( function functionTwo()) के साथ, फ़ंक्शन उस कोड के लिए उपलब्ध है जो फ़ंक्शन घोषित होने पर ऊपर चलता है।

ऐसा इसलिए है क्योंकि पहले संस्करण के साथ, फ़ंक्शन को fooरन टाइम पर चर को सौंपा जाता है । दूसरे में, फ़ंक्शन को उस पहचानकर्ता को, fooपार्स समय पर सौंपा जाता है ।

अधिक तकनीकी जानकारी

जावास्क्रिप्ट कार्यों को परिभाषित करने के तीन तरीके हैं।

  1. आपका पहला स्निपेट एक फंक्शन एक्सप्रेशन दिखाता है । इसमें फ़ंक्शन बनाने के लिए "फ़ंक्शन" ऑपरेटर का उपयोग करना शामिल है - उस ऑपरेटर का परिणाम किसी भी चर या ऑब्जेक्ट संपत्ति में संग्रहीत किया जा सकता है। फ़ंक्शन अभिव्यक्ति इस तरह से शक्तिशाली है। फ़ंक्शन एक्सप्रेशन को अक्सर "अनाम फ़ंक्शन" कहा जाता है, क्योंकि इसमें कोई नाम नहीं होता है,
  2. आपका दूसरा उदाहरण एक फ़ंक्शन घोषणा है । यह फ़ंक्शन बनाने के लिए "फ़ंक्शन" स्टेटमेंट का उपयोग करता है। फ़ंक्शन को पार्स समय पर उपलब्ध कराया जाता है और उस दायरे में कहीं भी बुलाया जा सकता है। आप इसे बाद में एक चर या वस्तु संपत्ति में संग्रहीत कर सकते हैं।
  3. किसी फ़ंक्शन को परिभाषित करने का तीसरा तरीका "फ़ंक्शन ()" निर्माता है , जो आपके मूल पोस्ट में नहीं दिखाया गया है। इसका उपयोग करने की अनुशंसा नहीं की जाती है क्योंकि यह उसी तरह से काम करता है जैसे eval()कि इसकी समस्याएं हैं।

103

ग्रेग के जवाब के लिए एक बेहतर व्याख्या

functionTwo();
function functionTwo() {
}

कोई त्रुटि क्यों? हमें हमेशा सिखाया गया था कि अभिव्यक्ति को ऊपर से नीचे तक निष्पादित किया जाता है (??)

चूंकि:

फ़ंक्शन घोषणाएँ और चर घोषणाएँ हमेशा स्थानांतरित की जाती हैं ( hoisted) जावास्क्रिप्ट दुभाषिया द्वारा उनके दायरे के शीर्ष पर अदृश्य रूप से। फ़ंक्शन पैरामीटर और भाषा-परिभाषित नाम, जाहिर है, पहले से ही वहां हैं। बे चेरी

इसका मतलब है कि इस तरह कोड:

functionOne();                  ---------------      var functionOne;
                                | is actually |      functionOne();
var functionOne = function(){   | interpreted |-->
};                              |    like     |      functionOne = function(){
                                ---------------      };

ध्यान दें कि घोषणाओं का असाइनमेंट भाग फहराया नहीं गया था। केवल नाम फहराया जाता है।

लेकिन फ़ंक्शन घोषणाओं के मामले में, पूरे फ़ंक्शन बॉडी को भी फहराया जाएगा :

functionTwo();              ---------------      function functionTwo() {
                            | is actually |      };
function functionTwo() {    | interpreted |-->
}                           |    like     |      functionTwo();
                            ---------------

फंक्शन विषय के बारे में स्पष्ट जानकारी के लिए HI सुहैल धन्यवाद। अब मेरा प्रश्न यह है कि कौन सा घोषणा घोषणा पदानुक्रम में पहली घोषणा होगी कि क्या चर घोषणा (functionOne) या फ़ंक्शन घोषणा (functionTwo) है?
शरथी आरबी

91

अन्य टिप्पणीकारों ने पहले से ही ऊपर दिए गए दो वेरिएंट के शब्दार्थ अंतर को कवर किया है। मैं एक शैलीगत अंतर को नोट करना चाहता था: केवल "असाइनमेंट" भिन्नता किसी अन्य ऑब्जेक्ट की संपत्ति सेट कर सकती है।

मैं अक्सर इस तरह के पैटर्न के साथ जावास्क्रिप्ट मॉड्यूल का निर्माण करता हूं:

(function(){
    var exports = {};

    function privateUtil() {
            ...
    }

    exports.publicUtil = function() {
            ...
    };

    return exports;
})();

इस पैटर्न के साथ, आपके सार्वजनिक कार्य सभी असाइनमेंट का उपयोग करेंगे, जबकि आपके निजी फ़ंक्शन घोषणा का उपयोग करते हैं।

(यह भी नोट करें कि असाइनमेंट में बयान के बाद अर्धविराम की आवश्यकता होनी चाहिए, जबकि घोषणा इसे प्रतिबंधित करती है।)


4
yuiblog.com/blog/2007/06/12/module-pattern मॉड्यूल पैटर्न के लिए प्राइमर्डियल संदर्भ है, जहां तक ​​मैं बता सकता हूं। (हालांकि यह लेख var foo = function(){...}निजी चर के लिए भी वाक्यविन्यास का उपयोग करता है ।
शॉन मैकमिलन

यह वास्तव में IE के कुछ पुराने संस्करणों में पूरी तरह से सच नहीं है। ( function window.onload() {}एक बात थी।)
Ry-

77

पहली विधि को दूसरे के लिए पसंद करने का एक उदाहरण है जब आपको किसी फ़ंक्शन की पिछली परिभाषाओं को ओवरराइड करने से बचने की आवश्यकता होती है।

साथ में

if (condition){
    function myfunction(){
        // Some code
    }
}

, यह myfunctionकिसी भी पिछली परिभाषा को खत्म कर देगा, क्योंकि यह पार्स-टाइम पर किया जाएगा।

जबकि

if (condition){
    var myfunction = function (){
        // Some code
    }
}

परिभाषित करने का सही काम करता है myfunctionकेवल जब conditionपूरा किया जाता है।


1
यह उदाहरण अच्छा है और पूर्णता के करीब है, लेकिन सुधार किया जा सकता है। बेहतर उदाहरण var myFunc = null;एक लूप के बाहर, या एक if / फारस / अन्य ब्लॉक के बाहर परिभाषित किया जाएगा । तब आप सशर्त रूप से एक ही चर के लिए विभिन्न कार्यों को असाइन कर सकते हैं। जेएस में, एक अपरिहार्य मूल्य को शून्य करने के लिए, फिर अपरिभाषित करने के लिए एक बेहतर सम्मेलन है। इसलिए, आपको myFunction को पहले अशक्त घोषित करना चाहिए, फिर बाद में, सशर्त रूप से असाइन करना चाहिए।
अलेक्जेंडर मिल्स

62

एक महत्वपूर्ण कारण आपके नाम स्थान के "रूट" के रूप में एक और केवल एक चर जोड़ना है ...

var MyNamespace = {}
MyNamespace.foo= function() {

}

या

var MyNamespace = {
  foo: function() {
  },
  ...
}

नाम रखने की कई तकनीकें हैं। यह अधिक उपलब्ध जावास्क्रिप्ट मॉड्यूल के ढेर के साथ महत्वपूर्ण हो गया है।

यह भी देखें कि मैं जावास्क्रिप्ट में नाम स्थान कैसे घोषित करूं?


3
ऐसा प्रतीत होता है इस सवाल का जवाब एक और सवाल से इस सवाल में विलय कर दिया गया था, और शब्दों सकता है एक छोटा सा के लिए असंबंधित होने लगते हैं इस सवाल। क्या आप उत्तर को संपादित करने पर विचार करेंगे ताकि यह विशेष रूप से इस प्रश्न पर निर्देशित हो? (पुनरावृत्ति के लिए; यह आपकी गलती नहीं है ... एक विलय प्रश्न का सिर्फ एक पक्ष-प्रभाव)। आप इसे हटा भी सकते हैं, और मुझे लगता है कि आप अपनी प्रतिष्ठा बनाए रखेंगे। या आप इसे छोड़ सकते हैं; चूंकि यह पुराना है, इसलिए यह एक बड़ा अंतर नहीं हो सकता है।
एंड्रयू बार्बर

55

उत्थापन जावास्क्रिप्ट दुभाषिया की क्रिया है जो सभी चर और फ़ंक्शन घोषणाओं को वर्तमान दायरे के शीर्ष पर ले जाती है।

हालांकि, केवल वास्तविक घोषणाओं को फहराया जाता है। असाइनमेंट्स को छोड़कर वे कहां हैं।

  • वैरिएबल / फंक्शन के पेज के अंदर घोषित किए गए हैं, वैश्विक उस पेज में कहीं भी पहुंच सकते हैं।
  • वेरिएबल / फंक्शन्स को फंक्शन के अंदर घोषित करने पर लोकल स्कोप होता है। इसका मतलब है कि वे फ़ंक्शन बॉडी (स्कोप) के अंदर उपलब्ध / एक्सेस किए गए हैं, वे फ़ंक्शन बॉडी के बाहर उपलब्ध नहीं हैं।

परिवर्तनशील

जावास्क्रिप्ट को शिथिल टाइप की भाषा कहा जाता है। जिसका अर्थ है कि जावास्क्रिप्ट चर किसी भी डेटा-प्रकार का मान रख सकते हैं । जावास्क्रिप्ट स्वचालित रूप से रनटाइम के दौरान प्रदान किए गए मूल्य / शाब्दिक के आधार पर चर-प्रकार को बदलने का ख्याल रखता है।

global_Page = 10;                                               var global_Page;      « undefined
    « Integer literal, Number Type.   -------------------       global_Page = 10;     « Number         
global_Page = 'Yash';                 |   Interpreted   |       global_Page = 'Yash'; « String
    « String literal, String Type.    «       AS        «       global_Page = true;   « Boolean 
var global_Page = true;               |                 |       global_Page = function (){          « function
    « Boolean Type                    -------------------                 var local_functionblock;  « undefined
global_Page = function (){                                                local_functionblock = 777 Number
    var local_functionblock = 777;                              };  
    // Assigning function as a data.
};  

समारोह

function Identifier_opt ( FormalParameterList_opt ) { 
      FunctionBody | sequence of statements

      « return;  Default undefined
      « return 'some data';
}
  • पृष्ठ के अंदर घोषित कार्यों को वैश्विक पहुंच वाले पृष्ठ के शीर्ष पर फहराया जाता है।
  • फ़ंक्शन-ब्लॉक के अंदर घोषित कार्यों को ब्लॉक के शीर्ष पर फहराया जाता है।
  • फ़ंक्शन का डिफ़ॉल्ट रिटर्न मान ' अपरिभाषित ' है, परिवर्तनीय घोषणा डिफ़ॉल्ट मूल्य भी 'अपरिभाषित'

    Scope with respect to function-block global. 
    Scope with respect to page undefined | not available.

समारोह घोषणा

function globalAccess() {                                  function globalAccess() {      
}                                  -------------------     }
globalAccess();                    |                 |     function globalAccess() { « Re-Defined / overridden.
localAccess();                     «   Hoisted  As   «         function localAccess() {
function globalAccess() {          |                 |         }
     localAccess();                -------------------         localAccess(); « function accessed with in globalAccess() only.
     function localAccess() {                              }
     }                                                     globalAccess();
}                                                          localAccess(); « ReferenceError as the function is not defined

समारोह अभिव्यक्ति

        10;                 « literal
       (10);                « Expression                (10).toString() -> '10'
var a;                      
    a = 10;                 « Expression var              a.toString()  -> '10'
(function invoke() {        « Expression Function
 console.log('Self Invoking');                      (function () {
});                                                               }) () -> 'Self Invoking'

var f; 
    f = function (){        « Expression var Function
    console.log('var Function');                                   f ()  -> 'var Function'
    };

चर के लिए सौंपा समारोह उदाहरण:

(function selfExecuting(){
    console.log('IIFE - Immediately-Invoked Function Expression');
}());

var anonymous = function (){
    console.log('anonymous function Expression');
};

var namedExpression = function for_InternalUSE(fact){
    if(fact === 1){
        return 1;
    }

    var localExpression = function(){
        console.log('Local to the parent Function Scope');
    };
    globalExpression = function(){ 
        console.log('creates a new global variable, then assigned this function.');
    };

    //return; //undefined.
    return fact * for_InternalUSE( fact - 1);   
};

namedExpression();
globalExpression();

जावास्क्रिप्ट के रूप में व्याख्या की

var anonymous;
var namedExpression;
var globalExpression;

anonymous = function (){
    console.log('anonymous function Expression');
};

namedExpression = function for_InternalUSE(fact){
    var localExpression;

    if(fact === 1){
        return 1;
    }
    localExpression = function(){
        console.log('Local to the parent Function Scope');
    };
    globalExpression = function(){ 
        console.log('creates a new global variable, then assigned this function.');
    };

    return fact * for_InternalUSE( fact - 1);    // DEFAULT UNDEFINED.
};

namedExpression(10);
globalExpression();

आप अलग-अलग ब्राउज़र के उपयोग से फ़ंक्शन की घोषणा, अभिव्यक्ति परीक्षण की जांच कर सकते हैं jsperf Test Runner


ES5 कंस्ट्रक्टर फंक्शन क्लासेस : फंक्शन ऑब्जेक्ट्स का उपयोग करके बनाया गया

जावास्क्रिप्ट फ़र्स्ट-क्लास ऑब्जेक्ट्स के रूप में कार्य करता है, इसलिए एक ऑब्जेक्ट होने के नाते, आप किसी फ़ंक्शन को गुण असाइन कर सकते हैं।

function Shape(id) { // Function Declaration
    this.id = id;
};
    // Adding a prototyped method to a function.
    Shape.prototype.getID = function () {
        return this.id;
    };
    Shape.prototype.setID = function ( id ) {
        this.id = id;
    };

var expFn = Shape; // Function Expression

var funObj = new Shape( ); // Function Object
funObj.hasOwnProperty('prototype'); // false
funObj.setID( 10 );
console.log( funObj.getID() ); // 10

ES6 ने एरो फंक्शन पेश किया : एक एरो फंक्शन एक्सप्रेशन का एक छोटा सिंटैक्स है, वे गैर-विधि कार्यों के लिए सबसे उपयुक्त हैं, और उन्हें कंस्ट्रक्टर के रूप में उपयोग नहीं किया जा सकता है।

ArrowFunction : ArrowParameters => ConciseBody

const fn = (item) => { return item & 1 ? 'Odd' : 'Even'; };
console.log( fn(2) ); // Even
console.log( fn(3) ); // Odd

3
एहम, आपका जवाब ... क्या यह अस्पष्ट नहीं है? अच्छी तरह से लिखा है, हालांकि खर्च करने और बहुत अधिक जानकारी लिखने के लिए +1।
डेनिश

40

मैं अपना जवाब सिर्फ इसलिए जोड़ रहा हूं क्योंकि बाकी सभी ने फहराए जाने वाले हिस्से को अच्छी तरह से कवर किया है।

मुझे आश्चर्य है कि अब तक कौन सा रास्ता बेहतर है, और http://jsperf.com के लिए धन्यवाद अब मुझे पता है :)

यहां छवि विवरण दर्ज करें

समारोह घोषणाएं तेजी से होती हैं, और वेब डे में वास्तव में क्या मायने रखता है? ;)


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

3
खैर, मुझे यह फ़ायरफ़ॉक्स के साथ अन्य तरीके से मिला। jsperf.com/sandytest
संदीप नायक

बस एक अद्यतन, चूंकि मैं अब जावास्क्रिप्ट में पूर्ण कार्यात्मक प्रोग्रामिंग शैली चला गया हूं, मैं कभी भी घोषणाओं का उपयोग नहीं करता हूं, केवल फ़ंक्शन अभिव्यक्तियों का उपयोग करता हूं ताकि मैं अपने चर नामों से अपने कार्यों को चेन और कॉल कर सकूं। रामदास देखें ...
लियोन गबन

1
@SandeepNayak मैं फ़ायरफ़ॉक्स 50.0.0 / विंडोज 7 0.0.0 में अपना परीक्षण चलाता हूं, और यह वास्तव में लियोन के समान है। इसलिए यदि आपका परीक्षण सही है, तो मैं निष्कर्ष निकालूंगा कि jsperf के परीक्षण सूचक नहीं हैं, और यह सब आपके ब्राउज़र और / या OS संस्करण पर निर्भर करता है, या उस विशेष क्षण में वर्तमान मशीन की विशेष स्थिति में।
१०:४० को

33

एक फ़ंक्शन घोषणा और एक चर के लिए सौंपी गई फ़ंक्शन अभिव्यक्ति एक बार बंधन स्थापित होने के बाद ही व्यवहार करती है।

हालाँकि, फ़ंक्शन ऑब्जेक्ट वास्तव में इसके चर के साथ कैसे और कब जुड़ा हुआ है, इसमें एक अंतर है । यह अंतर जावास्क्रिप्ट में चर उत्थापन नामक तंत्र के कारण है ।

मूल रूप से, सभी फ़ंक्शन घोषणाएं और चर घोषणाएं उस फ़ंक्शन के शीर्ष पर लहराई जाती हैं जिसमें घोषणा होती है (यही कारण है कि हम कहते हैं कि जावास्क्रिप्ट में फ़ंक्शन गुंजाइश है )।

  • जब एक फ़ंक्शन घोषणा को फहराया जाता है, तो फ़ंक्शन बॉडी "अनुसरण करता है" इसलिए जब फ़ंक्शन बॉडी का मूल्यांकन किया जाता है, तो चर तुरंत एक फ़ंक्शन ऑब्जेक्ट के लिए बाध्य होगा।

  • जब एक चर घोषणा को फहराया जाता है, तो प्रारंभ का पालन नहीं होता है , लेकिन "पीछे रह जाता है"। चर को undefinedफ़ंक्शन बॉडी के प्रारंभ में प्रारंभ किया जाता है, और कोड में इसके मूल स्थान पर एक मान दिया जाएगा । (वास्तव में, इसे हर उस स्थान पर एक मान दिया जाएगा जहाँ एक ही नाम के साथ एक चर की घोषणा होती है।)

फहराए जाने का क्रम भी महत्वपूर्ण है: फ़ंक्शन घोषणाएं एक ही नाम के साथ परिवर्तनीय घोषणाओं पर वरीयता लेती हैं, और अंतिम फ़ंक्शन घोषणा एक ही नाम के साथ पिछले फ़ंक्शन घोषणाओं पर पूर्वता लेती है।

कुछ उदाहरण...

var foo = 1;
function bar() {
  if (!foo) {
    var foo = 10 }
  return foo; }
bar() // 10

वैरिएबल fooफ़ंक्शन के शीर्ष पर फहराया जाता है , undefinedजिसे इनिशियलाइज़ किया !fooजाता है true, इसलिए fooइसे असाइन किया जाता है 10fooके बाहर barकी गुंजाइश नहीं भूमिका निभाता है और अछूता है।

function f() {
  return a; 
  function a() {return 1}; 
  var a = 4;
  function a() {return 2}}
f()() // 2

function f() {
  return a;
  var a = 4;
  function a() {return 1};
  function a() {return 2}}
f()() // 2

चर घोषणाएं, चर घोषणाओं और अंतिम कार्य घोषणा "लाठी" पर पूर्वता लेती हैं।

function f() {
  var a = 4;
  function a() {return 1}; 
  function a() {return 2}; 
  return a; }
f() // 4

इस उदाहरण aमें दूसरे फ़ंक्शन घोषणा के मूल्यांकन के परिणामस्वरूप फ़ंक्शन ऑब्जेक्ट के साथ प्रारंभ किया जाता है, और उसके बाद असाइन किया जाता है 4

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

यहाँ फ़ंक्शन डिक्लेरेशन को पहले घोषित किया जाता है, जिसे वेरिएबल घोषित और इनिशियलाइज़ किया जाता है a। अगला, यह चर सौंपा गया है 10। दूसरे शब्दों में: असाइनमेंट बाहरी वैरिएबल को असाइन नहीं करता है a


3
आपके पास समापन ब्रेसिज़ रखने के लिए थोड़ा अजीब तरीका है। क्या आप पायथन कोडर हैं? ऐसा लगता है कि आप जावास्क्रिप्ट को पायथन की तरह बनाने की कोशिश करते हैं। मुझे डर है कि यह अन्य लोगों के लिए भ्रामक है। अगर मुझे आपका जावास्क्रिप्ट कोड बनाए रखना है तो मैं आपके कोड को पहले एक ऑटोमैटिक प्रेटीप्रिन्टर के माध्यम से जाने दूंगा।
nalply

1
बहुत बढ़िया पोस्ट। एक 'सेल्फ-एक्ज़ीक्यूटिंग फंक्शन' या 'तुरंत इन्वॉल्व्ड फंक्शन एक्सप्रेशन' देखने में काफी आसान होना चाहिए और उसकी शैली वरीयता को उसके पद से नहीं हटना चाहिए - जो कि सटीक है और 'उत्थापन' को पूरी तरह से सारांशित करता है। +1
रिक्सिनिन

32

पहला उदाहरण एक फ़ंक्शन घोषणा है:

function abc(){}

दूसरा उदाहरण एक फ़ंक्शन अभिव्यक्ति है:

var abc = function() {};

मुख्य अंतर यह है कि उन्हें कैसे उठाया जाता है (उठाया और घोषित किया जाता है)। पहले उदाहरण में, पूरे फ़ंक्शन घोषणा को फहराया जाता है। दूसरे उदाहरण में केवल var 'abc' को फहराया जाता है, इसका मान (फ़ंक्शन) अपरिभाषित होगा, और फ़ंक्शन स्वयं उस स्थिति में रहता है जिसे वह घोषित किया गया है।

अगर सरल शब्द में कहा जाए तो:

//this will work
abc(param);
function abc(){}

//this would fail
abc(param);
var abc = function() {}

इस विषय के बारे में अधिक अध्ययन करने के लिए मैं आपको इस लिंक की दृढ़ता से सलाह देता हूं


1
आपका उदाहरण शीर्ष उत्तर के समान है
गौतम

इस उत्तर को पोस्ट करने का मुख्य कारण नीचे लिंक प्रदान करना था। यह वह टुकड़ा था जो मेरे लिए उपरोक्त प्रश्न को पूरी तरह से समझने के लिए गायब था।
sl5555

1
यह बहुत अच्छा है कि आप लिंक साझा करना चाहते हैं। लेकिन एसओ में अतिरिक्त जानकारी के लिंक, या तो प्रश्न या आपके पसंदीदा उत्तर पर एक टिप्पणी होनी चाहिए। यह एक लंबे, जटिल पृष्ठ को अव्यवस्थित करने के लिए बहुत ही उप-इष्टतम है जैसे कि बार-बार जानकारी के साथ इसके अंत में एक भी उपयोगी लिंक जोड़ना। नहीं, आपको लिंक प्रदान करने के लिए प्रतिनिधि नहीं मिलेंगे, लेकिन आप समुदाय की मदद करेंगे।
एक्सएमएल

30

कोड रखरखाव लागत के संदर्भ में, नामित कार्य अधिक बेहतर हैं:

  • उस जगह से स्वतंत्र जहां उन्हें घोषित किया गया है (लेकिन अभी तक सीमित है)।
  • सशर्त आरंभीकरण जैसी गलतियों के प्रति अधिक प्रतिरोधी (यदि आप चाहते हैं तो अभी भी ओवरराइड करने में सक्षम हैं)।
  • स्कोप कार्यक्षमता के अलग-अलग स्थानीय कार्यों को आवंटित करके कोड अधिक पठनीय हो जाता है। आमतौर पर कार्यक्षेत्र में कार्यक्षमता सबसे पहले जाती है, उसके बाद स्थानीय कार्यों की घोषणा होती है।
  • डीबगर में आप "अनाम / मूल्यांकित" फ़ंक्शन के बजाय कॉल स्टैक पर फ़ंक्शन का नाम स्पष्ट रूप से देखेंगे।

मुझे संदेह है कि नामित कार्यों के लिए अधिक PROS अनुसरण कर रहे हैं। और नामित कार्यों के लाभ के रूप में सूचीबद्ध क्या अनाम लोगों के लिए एक नुकसान है।

ऐतिहासिक रूप से, अनाम फ़ंक्शंस जावास्क्रिप्ट की अक्षमता से नाम के कार्यों के साथ सदस्यों की सूची के लिए एक भाषा के रूप में दिखाई दिया:

{
    member:function() { /* How do I make "this.member" a named function? */
    }
}

2
इस बात की पुष्टि करने के लिए परीक्षण हैं: blog.firsov.net/2010/01/… JS प्रदर्शन परीक्षण - कार्यक्षेत्र और नामित कार्य - विश्लेषिकी
साशा फिरोजव

25

कंप्यूटर विज्ञान के संदर्भ में, हम अनाम कार्यों और नामित कार्यों के बारे में बात करते हैं। मुझे लगता है कि सबसे महत्वपूर्ण अंतर यह है कि एक अनाम फ़ंक्शन एक नाम से बाध्य नहीं है, इसलिए नाम अनाम फ़ंक्शन। जावास्क्रिप्ट में यह एक प्रथम श्रेणी की वस्तु है जिसे गतिशील रूप से रनटाइम पर घोषित किया गया है।

अनाम फ़ंक्शंस और लैम्ब्डा कैलकुलस के बारे में अधिक जानकारी के लिए, विकिपीडिया एक अच्छी शुरुआत है ( http://en.wikipedia.org/wiki/Anonymous_function )।


ES2015 के रूप में (आपके उत्तर पोस्ट किए जाने के साढ़े छह साल बाद), प्रश्न में दोनों कार्यों का नाम दिया गया है।
टीजे क्राउडर

25

मैं अपने कोड में चर दृष्टिकोण का उपयोग एक बहुत ही विशिष्ट कारण के लिए करता हूं, जिसका सिद्धांत ऊपर सार तरीके से कवर किया गया है, लेकिन एक उदाहरण मेरे जैसे कुछ लोगों को सीमित जावास्क्रिप्ट विशेषज्ञता के साथ मदद कर सकता है।

मेरे पास कोड है जो मुझे 160 स्वतंत्र रूप से डिज़ाइन किए गए ब्रांडिंग के साथ चलाने की आवश्यकता है। अधिकांश कोड साझा फ़ाइलों में है, लेकिन ब्रांडिंग-विशिष्ट सामान एक अलग फ़ाइल में है, प्रत्येक ब्रांडिंग के लिए एक है।

कुछ ब्रांडिंग के लिए विशिष्ट कार्यों की आवश्यकता होती है, और कुछ नहीं करते हैं। कभी-कभी मुझे नई ब्रांडिंग-विशिष्ट चीजों को करने के लिए नए कार्यों को जोड़ना पड़ता है। मैं साझा कोड को बदलने के लिए खुश हूं, लेकिन मैं ब्रांडिंग फाइलों के सभी 160 सेटों को बदलना नहीं चाहता।

चर सिंटैक्स का उपयोग करके, मैं साझा कोड में चर (एक फ़ंक्शन पॉइंटर अनिवार्य रूप से) की घोषणा कर सकता हूं और या तो एक तुच्छ स्टब फ़ंक्शन असाइन कर सकता हूं, या शून्य पर सेट कर सकता हूं।

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

उपरोक्त लोगों की टिप्पणियों से, मैं इकट्ठा करता हूं कि एक स्थिर फ़ंक्शन को भी फिर से परिभाषित करना संभव हो सकता है, लेकिन मुझे लगता है कि चर समाधान अच्छा और स्पष्ट है।


25

ग्रेग का उत्तर काफी अच्छा है, लेकिन मैं अभी भी इसमें कुछ जोड़ना चाहूंगा जो मैंने अभी देखा है डगलस क्रॉकफोर्ड वीडियो को ।

समारोह अभिव्यक्ति:

var foo = function foo() {};

समारोह विवरण:

function foo() {};

फ़ंक्शन स्टेटमेंट के लिए सिर्फ एक शॉर्टहैंड है var साथ स्टेटमेंट के हैfunction वैल्यू वाले ।

इसलिए

function foo() {};

तक फैलता है

var foo = function foo() {};

जिसका विस्तार आगे है:

var foo = undefined;
foo = function foo() {};

और वे दोनों कोड के शीर्ष पर फहराए जाते हैं।

वीडियो से स्क्रीनशॉट


7
क्षमा करें, लेकिन यह गलत है - मुझे नहीं पता कि क्रॉकफोर्ड उस स्लाइड में क्या कहना चाह रहा है। फ़ंक्शन और वैरिएबल दोनों घोषणाएँ हमेशा अपने दायरे के ऊपर फहराई जाती हैं। अंतर यह है कि चर असाइनमेंट (चाहे आप इसे एक स्ट्रिंग, बूलियन या फ़ंक्शन के साथ असाइन कर रहे हैं) को शीर्ष पर नहीं फहराया जाता है जबकि फ़ंक्शन बॉडी (फ़ंक्शन घोषणा का उपयोग करके) होते हैं।
थॉमस हेमैन

इन कोड उदाहरणों पर एक नज़र डालें: gist.github.com/cyberthom/36603fbc20de8e04fd09
थॉमस हेमैन

23

नीचे सूचीबद्ध कार्यों के दो अलग-अलग घोषणाओं के बीच चार उल्लेखनीय तुलनाएं हैं।

  1. फ़ंक्शन की उपलब्धता (गुंजाइश)

निम्न कार्य क्योंकि function add()निकटतम ब्लॉक में स्कोप किया गया है:

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

function add(a, b){
  return a + b;
}

निम्न कार्य नहीं करता है क्योंकि चर को फ़ंक्शन मान को असाइन किए जाने से पहले चर कहा जाता है add

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

var add=function(a, b){
  return a + b;
}

उपरोक्त कोड नीचे दिए गए कोड की कार्यक्षमता में समान है। ध्यान दें कि स्पष्ट रूप से असाइन add = undefinedकरना अतिश्योक्तिपूर्ण है क्योंकि बस कर रहा var add;है के रूप में सटीक है var add=undefined

var add = undefined;

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

add = function(a, b){
  return a + b;
}

निम्नलिखित काम नहीं करता है क्योंकि var add=सुपरसाइड करता है function add()

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

var add=function add(a, b){
  return a + b;
}

  1. (फ़ंक्शन) .name

किसी फ़ंक्शन function thefuncname(){}का नाम thefuncname है जब इसे इस प्रकार घोषित किया जाता है।

function foobar(a, b){}

console.log(foobar.name);

var a = function foobar(){};

console.log(a.name);

अन्यथा, यदि कोई फ़ंक्शन के रूप में घोषित किया गया है function(){}, तो फ़ंक्शन .name फ़ंक्शन को संग्रहीत करने के लिए उपयोग किया जाने वाला पहला चर है।

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

console.log(a.name);
console.log(b.name);

यदि फ़ंक्शन में कोई चर सेट नहीं हैं, तो फ़ंक्शन नाम रिक्त स्ट्रिंग ( "") है।

console.log((function(){}).name === "");

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

var a = function(){};
var b = a;
var c = b;

console.log(a.name);
console.log(b.name);
console.log(c.name);

  1. प्रदर्शन

Google के V8 और फ़ायरफ़ॉक्स के स्पाइडरमोंकी में कुछ माइक्रोसेकंड JIST संकलन अंतर हो सकता है, लेकिन अंततः परिणाम बिल्कुल वही है। यह साबित करने के लिए, आइए दो खाली कोड स्निपेट्स की गति की तुलना करके माइक्रोबैनचर्च में JSPerf की दक्षता की जांच करें। JSPerf परीक्षण यहां पाए जाते हैं । और, यहाँ पाया गया jsben.ch टेस्टसेयर । जैसा कि आप देख सकते हैं, जब कोई नहीं होना चाहिए, तो एक उल्लेखनीय अंतर है। यदि आप वास्तव में मेरी तरह एक प्रदर्शन सनकी हैं, तो यह आपके दायरे में चर और कार्यों की संख्या को कम करने और विशेष रूप से बहुरूपता (जैसे दो अलग-अलग प्रकारों को संग्रहीत करने के लिए एक ही चर का उपयोग करने के रूप में) को कम करने की कोशिश करते हुए आपके लायक हो सकता है।

  1. परिवर्तनीय उत्परिवर्तन

जब आप varकिसी वैरिएबल को घोषित करने के लिए कीवर्ड का उपयोग करते हैं , तो आप इस तरह वैरिएबल को एक अलग मान दे सकते हैं।

(function(){
    "use strict";
    var foobar = function(){}; // initial value
    try {
        foobar = "Hello World!"; // new value
        console.log("[no error]");
    } catch(error) {
        console.log("ERROR: " + error.message);
    }
    console.log(foobar, window.foobar);
})();

हालांकि, जब हम कॉन्स्ट-स्टेटमेंट का उपयोग करते हैं, तो चर संदर्भ अपरिवर्तनीय हो जाता है। इसका मतलब है कि हम वैरिएबल को एक नया मान नहीं दे सकते हैं। कृपया ध्यान दें, हालांकि यह चर की सामग्री को अपरिवर्तनीय नहीं बनाता है: यदि आप करते हैं const arr = [], तो आप अभी भी कर सकते हैं arr[10] = "example"। केवल ऐसा कुछ करने arr = "new value"या arr = []नीचे देखने पर कोई त्रुटि होगी।

(function(){
    "use strict";
    const foobar = function(){}; // initial value
    try {
        foobar = "Hello World!"; // new value
        console.log("[no error]");
    } catch(error) {
        console.log("ERROR: " + error.message);
    }
    console.log(foobar, window.foobar);
})();

दिलचस्प बात यह है कि अगर हम चर को घोषित करते हैं function funcName(){}, तो चर की अपरिहार्यता उसी के साथ घोषित करने के समान है var

(function(){
    "use strict";
    function foobar(){}; // initial value
    try {
        foobar = "Hello World!"; // new value
        console.log("[no error]");
    } catch(error) {
        console.log("ERROR: " + error.message);
    }
    console.log(foobar, window.foobar);
})();

"निकटतम ब्लॉक" क्या है

"निकटतम ब्लॉक" निकटतम "फ़ंक्शन" है (एसिंक्रोनस फ़ंक्शन, जनरेटर फ़ंक्शन और एसिंक्रोनस जनरेटर फ़ंक्शन सहित)। हालांकि, दिलचस्प बात यह है function functionName() {}कि var functionName = function() {}जब गैर-क्लोजर ब्लॉक में बाहर की वस्तुओं को बंद करने की बात कही जाती है तो ऐसा व्यवहार होता है । ध्यान से देखें।

  • साधारण var add=function(){}

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}');
  }
} catch(e) {
  console.log("Is a block");
}
var add=function(a, b){return a + b}

  • साधारण function add(){}

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
function add(a, b){
  return a + b;
}

  • समारोह

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(function () {
    function add(a, b){
      return a + b;
    }
})();

  • वक्तव्य (जैसे if, else, for, while, try/ catch/ finally, switch, do/ while, with)

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
{
    function add(a, b){
      return a + b;
    }
}

  • एरो फंक्शन के साथ var add=function()

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(() => {
    var add=function(a, b){
      return a + b;
    }
})();

  • तीर के साथ समारोह function add()

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(() => {
    function add(a, b){
      return a + b;
    }
})();


यह स्वीकार किए जाते हैं और सबसे उत्कट जवाब है
हारून जॉन साबू

18

@EugeneLazutkin एक उदाहरण देता है जहां वह एक निर्दिष्ट फ़ंक्शनshortcut() को अपने लिए एक आंतरिक संदर्भ के रूप में उपयोग करने में सक्षम होने का नाम देता है। जॉन रेजिग एक और उदाहरण देता है - अपने लर्निंग एडवांस जावास्क्रिप्ट ट्यूटोरियल में किसी अन्य ऑब्जेक्ट को सौंपे गए पुनरावर्ती फ़ंक्शन की प्रतिलिपि बनाना । प्रॉपर्टीज में फ़ंक्शंस असाइन करते समय सख्ती से सवाल यहाँ नहीं है, मैं सक्रिय रूप से ट्यूटोरियल को आज़माने की सलाह देता हूं - ऊपरी दाएं कोने में बटन पर क्लिक करके कोड चलाएं, और अपनी पसंद के अनुसार संपादित करने के लिए कोड पर डबल क्लिक करें।

ट्यूटोरियल से उदाहरण: पुनरावर्ती कॉल में yell():

मूल निंजा ऑब्जेक्ट को हटा दिए जाने पर टेस्ट विफल हो जाते हैं। (पेज 13)

var ninja = { 
  yell: function(n){ 
    return n > 0 ? ninja.yell(n-1) + "a" : "hiy"; 
  } 
}; 
assert( ninja.yell(4) == "hiyaaaa", "A single object isn't too bad, either." ); 

var samurai = { yell: ninja.yell }; 
var ninja = null; 

try { 
  samurai.yell(4); 
} catch(e){ 
  assert( false, "Uh, this isn't good! Where'd ninja.yell go?" ); 
}

यदि आप उस फ़ंक्शन का नाम देते हैं जिसे पुनरावर्ती कहा जाएगा, तो परीक्षण पास हो जाएंगे। (पेज 14)

var ninja = { 
  yell: function yell(n){ 
    return n > 0 ? yell(n-1) + "a" : "hiy"; 
  } 
}; 
assert( ninja.yell(4) == "hiyaaaa", "Works as we would expect it to!" ); 

var samurai = { yell: ninja.yell }; 
var ninja = {}; 
assert( samurai.yell(4) == "hiyaaaa", "The method correctly calls itself." );

17

एक अन्य अंतर जो अन्य उत्तरों में वर्णित नहीं है, वह यह है कि यदि आप अनाम फ़ंक्शन का उपयोग करते हैं

var functionOne = function() {
    // Some code
};

और एक निर्माता के रूप में उपयोग करें

var one = new functionOne();

तब one.constructor.nameपरिभाषित नहीं किया जाएगा। Function.nameगैर-मानक है, लेकिन फ़ायरफ़ॉक्स, क्रोम, अन्य वेबकिट-व्युत्पन्न ब्राउज़र और IE 9+ द्वारा समर्थित है।

साथ में

function functionTwo() {
    // Some code
}
two = new functionTwo();

इसके साथ एक स्ट्रिंग के रूप में निर्माणकर्ता का नाम पुनर्प्राप्त करना संभव है two.constructor.name


पहले मामले में नाम को परिभाषित नहीं किया जाएगा क्योंकि इसका अनाम कार्य किसी चर को सौंपा गया है। मुझे लगता है कि अनाम शब्द का आविष्कार उन चीजों के लिए किया गया था, जिनका नाम उनके नाम पर परिभाषित नहीं है :)
ओम शंकर

इस उदाहरण में दो = नया एक वैश्विक कार्य बन जाता है क्योंकि कोई भी संस्करण
वकास ताहिर

16

पहला एक (फ़ंक्शन doSomething (x)) ऑब्जेक्ट नोटेशन का हिस्सा होना चाहिए।

दूसरा वाला ( var doSomething = function(x){ alert(x);}) बस एक अनाम फ़ंक्शन बना रहा है और इसे एक वैरिएबल को असाइन कर रहा है,doSomething ,। इसलिए doSomething () फ़ंक्शन को कॉल करेगा।

आप जानना चाह सकते हैं कि फंक्शन डिक्लेरेशन और फंक्शन एक्सप्रेशन क्या है।

एक फ़ंक्शन घोषणा, चर असाइनमेंट की आवश्यकता के बिना एक नामित फ़ंक्शन चर को परिभाषित करता है। फ़ंक्शन की घोषणाएं स्टैंडअलोन निर्माणों के रूप में होती हैं और गैर-फ़ंक्शन ब्लॉकों के भीतर नेस्टेड नहीं की जा सकती हैं।

function foo() {
    return 3;
}

ECMA 5 (13.0) सिंटैक्स को
फ़ंक्शन आइडेंटिफ़ायर (FormalParameterList ऑप्ट ) { फंक्शनबॉडी } के रूप में परिभाषित करता है

ऊपर की स्थिति में फ़ंक्शन नाम इसके दायरे में और इसके माता-पिता के दायरे में दिखाई देता है (अन्यथा यह अनुपलब्ध होगा)।

और एक फ़ंक्शन अभिव्यक्ति में

एक फ़ंक्शन एक्सप्रेशन एक फ़ंक्शन को एक बड़े एक्सप्रेशन सिंटैक्स (आमतौर पर एक चर असाइनमेंट) के एक भाग के रूप में परिभाषित करता है। फ़ंक्शंस एक्सप्रेशन के माध्यम से परिभाषित फ़ंक्शंस का नाम या अनाम हो सकता है। फ़ंक्शन अभिव्यक्तियों को "फ़ंक्शन" से शुरू नहीं करना चाहिए।

// Anonymous function expression
var a = function() {
    return 3;
}

// Named function expression
var a = function foo() {
    return 3;
}

// Self-invoking function expression
(function foo() {
    alert("hello!");
})();

ECMA 5 (13.0) सिंटैक्स को
फ़ंक्शन आइडेंटिफ़ायर ऑप्ट (FormalParameterList ऑप्ट ) { फंक्शनब्ली } के रूप में परिभाषित करता है


16

मैं नीचे दिए गए अंतरों को सूचीबद्ध कर रहा हूं:

  1. एक फ़ंक्शन घोषणा को कोड में कहीं भी रखा जा सकता है। भले ही कोड में परिभाषा दिखाई देने से पहले इसे लागू किया जाता है, यह निष्पादित हो जाता है क्योंकि फ़ंक्शन घोषणा स्मृति के लिए प्रतिबद्ध है या एक तरह से इसे फहराया जाता है, इससे पहले कि पृष्ठ में कोई अन्य कोड निष्पादन शुरू हो जाए।

    नीचे दिए गए फ़ंक्शन पर एक नज़र डालें:

    function outerFunction() {
        function foo() {
           return 1;
        }
        return foo();
        function foo() {
           return 2;
        }
    }
    alert(outerFunction()); // Displays 2

    ऐसा इसलिए है, क्योंकि निष्पादन के दौरान, ऐसा दिखता है: -

    function foo() {  // The first function declaration is moved to top
        return 1;
    }
    function foo() {  // The second function declaration is moved to top
        return 2;
    }
    function outerFunction() {
        return foo();
    }
    alert(outerFunction()); //So executing from top to bottom,
                            //the last foo() returns 2 which gets displayed

    एक फ़ंक्शन अभिव्यक्ति, यदि इसे कॉल करने से पहले परिभाषित नहीं किया गया है, तो त्रुटि होगी। इसके अलावा, यहाँ फ़ंक्शन डेफिनेशन स्वयं को शीर्ष पर नहीं ले जाया गया है या फ़ंक्शन घोषणाओं की तरह मेमोरी के लिए प्रतिबद्ध है। लेकिन जिस वेरिएबल को हम असाइन करते हैं वह फंक्शन हो जाता है और अपरिभाषित हो जाता है।

    फ़ंक्शन अभिव्यक्तियों का उपयोग करते हुए समान फ़ंक्शन:

    function outerFunction() {
        var foo = function() {
           return 1;
        }
        return foo();
        var foo = function() {
           return 2;
        }
    }
    alert(outerFunction()); // Displays 1

    ऐसा इसलिए है क्योंकि निष्पादन के दौरान, ऐसा दिखता है:

    function outerFunction() {
       var foo = undefined;
       var foo = undefined;
    
       foo = function() {
          return 1;
       };
       return foo ();
       foo = function() {   // This function expression is not reachable
          return 2;
       };
    }
    alert(outerFunction()); // Displays 1
  2. ऐसा लगता है कि गैर-समारोह ब्लॉक में समारोह घोषणाओं लिखने के लिए सुरक्षित नहीं है , तो इसलिए कि वे सुलभ नहीं होगा।

    if (test) {
        function x() { doSomething(); }
    }
  3. नीचे दी गई फ़ंक्शन की तरह नामांकित अभिव्यक्ति, संस्करण 9 से पहले इंटरनेट एक्सप्लोरर ब्राउज़रों में काम नहीं कर सकती है।

    var today = function today() {return new Date()}

1
@ अर्जुन अगर सालों पहले एक सवाल पूछा जाता है तो क्या समस्या है? एक उत्तर से न केवल ओपी को लाभ होता है, बल्कि संभावित रूप से सभी एसओ उपयोगकर्ताओं को, जब कोई प्रश्न पूछा जाता है, तो कोई फर्क नहीं पड़ता। और उन सवालों के जवाब देने में क्या गलत है जिनके पास पहले से ही एक स्वीकृत जवाब है?
संतिबेलर्स

1
@ अर्जुन आपको पुराने सवालों का जवाब देना समझ में नहीं आता है। अगर ऐसा होता, तो एसओ के पास ऐसा अवरोध होता। कल्पना कीजिए कि एपीआई में बदलाव है (इस प्रश्न के संदर्भ में नहीं) और किसी ने इसे स्पॉट किया और नए एपीआई के साथ एक उत्तर प्रदान करता है, क्या इसकी अनुमति नहीं होनी चाहिए ?? जब तक और जब तक जवाब का कोई मतलब नहीं है और यहाँ से संबंधित नहीं है, तब तक इसे हटा दिया जाएगा और स्वचालित रूप से हटा दिया जाएगा। आप इसके साथ परेशान करने की जरूरत नहीं है !!!!
सुधांशु चौधरी

15

यदि आप वस्तुओं को बनाने के लिए उन कार्यों का उपयोग करेंगे, तो आपको मिलेगा:

var objectOne = new functionOne();
console.log(objectOne.__proto__); // prints "Object {}" because constructor is an anonymous function

var objectTwo = new functionTwo();
console.log(objectTwo.__proto__); // prints "functionTwo {}" because constructor is a named function

मैं इसे पुन: पेश नहीं कर सकता। console.log(objectOne.__proto__);मेरे कंसोल में "functionOne {}" प्रिंट करता है। किसी भी विचार क्यों यह मामला हो सकता है?
माइक

मैं इसे पुन: पेश नहीं कर सकता।
daremkd

1
यह आपके डिबगर की क्षमता है (लॉग ऑब्जेक्ट के "वर्ग" को प्रदर्शित करने के लिए), और ज्यादातर लोग इन दिनों गुमनाम फ़ंक्शन अभिव्यक्तियों के लिए भी एक नाम प्राप्त करने में सक्षम हैं। Btw, आपको स्पष्ट करना चाहिए कि दोनों उदाहरणों के बीच कोई कार्यात्मक अंतर नहीं है।
बर्गी

12

"नामित फ़ंक्शन स्टैक ट्रैस में दिखाई देते हैं" तर्क के प्रकाश में, आधुनिक जावास्क्रिप्ट इंजन वास्तव में अनाम कार्यों का प्रतिनिधित्व करने में काफी सक्षम हैं।

इस लेखन के रूप में, V8, स्पाइडरमोंकी, चक्र और नाइट्रो हमेशा अपने नाम से नामित कार्यों का उल्लेख करते हैं। वे लगभग हमेशा अपने पहचानकर्ता द्वारा एक अनाम फ़ंक्शन का संदर्भ देते हैं यदि यह एक है।

स्पाइडरमोनीक एक अन्य फ़ंक्शन से लौटे एक अनाम फ़ंक्शन का नाम पता लगा सकता है। बाकी नहीं कर सकते।

यदि आप वास्तव में, वास्तव में चाहते थे कि आपका पुनरावृत्ति और सफलता कॉलबैक ट्रेस में दिखाई दे, तो आप उन लोगों को भी नाम दे सकते हैं ...

[].forEach(function iterator() {});

लेकिन अधिकांश भाग के लिए यह अधिक तनावपूर्ण नहीं है।

हार्नेस ( फिडल )

'use strict';

var a = function () {
    throw new Error();
},
    b = function b() {
        throw new Error();
    },
    c = function d() {
        throw new Error();
    },
    e = {
        f: a,
        g: b,
        h: c,
        i: function () {
            throw new Error();
        },
        j: function j() {
            throw new Error();
        },
        k: function l() {
            throw new Error();
        }
    },
    m = (function () {
        return function () {
            throw new Error();
        };
    }()),
    n = (function () {
        return function n() {
            throw new Error();
        };
    }()),
    o = (function () {
        return function p() {
            throw new Error();
        };
    }());

console.log([a, b, c].concat(Object.keys(e).reduce(function (values, key) {
    return values.concat(e[key]);
}, [])).concat([m, n, o]).reduce(function (logs, func) {

    try {
        func();
    } catch (error) {
        return logs.concat('func.name: ' + func.name + '\n' +
                           'Trace:\n' +
                           error.stack);
        // Need to manually log the error object in Nitro.
    }

}, []).join('\n\n'));

वी 8

func.name: 
Trace:
Error
    at a (http://localhost:8000/test.js:4:11)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: b
Trace:
Error
    at b (http://localhost:8000/test.js:7:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: d
Trace:
Error
    at d (http://localhost:8000/test.js:10:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: 
Trace:
Error
    at a (http://localhost:8000/test.js:4:11)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: b
Trace:
Error
    at b (http://localhost:8000/test.js:7:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: d
Trace:
Error
    at d (http://localhost:8000/test.js:10:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: 
Trace:
Error
    at e.i (http://localhost:8000/test.js:17:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: j
Trace:
Error
    at j (http://localhost:8000/test.js:20:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: l
Trace:
Error
    at l (http://localhost:8000/test.js:23:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: 
Trace:
Error
    at http://localhost:8000/test.js:28:19
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: n
Trace:
Error
    at n (http://localhost:8000/test.js:33:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: p
Trace:
Error
    at p (http://localhost:8000/test.js:38:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27 test.js:42

मकड़ीनुमा बन्दर

func.name: 
Trace:
a@http://localhost:8000/test.js:4:5
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: b
Trace:
b@http://localhost:8000/test.js:7:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: d
Trace:
d@http://localhost:8000/test.js:10:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: 
Trace:
a@http://localhost:8000/test.js:4:5
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: b
Trace:
b@http://localhost:8000/test.js:7:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: d
Trace:
d@http://localhost:8000/test.js:10:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: 
Trace:
e.i@http://localhost:8000/test.js:17:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: j
Trace:
j@http://localhost:8000/test.js:20:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: l
Trace:
l@http://localhost:8000/test.js:23:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: 
Trace:
m</<@http://localhost:8000/test.js:28:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: n
Trace:
n@http://localhost:8000/test.js:33:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: p
Trace:
p@http://localhost:8000/test.js:38:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1

चक्र

func.name: undefined
Trace:
Error
   at a (http://localhost:8000/test.js:4:5)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at b (http://localhost:8000/test.js:7:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at d (http://localhost:8000/test.js:10:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at a (http://localhost:8000/test.js:4:5)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at b (http://localhost:8000/test.js:7:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at d (http://localhost:8000/test.js:10:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at e.i (http://localhost:8000/test.js:17:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at j (http://localhost:8000/test.js:20:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at l (http://localhost:8000/test.js:23:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at Anonymous function (http://localhost:8000/test.js:28:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at n (http://localhost:8000/test.js:33:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at p (http://localhost:8000/test.js:38:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)

नाइट्रो

func.name: 
Trace:
a@http://localhost:8000/test.js:4:22
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: b
Trace:
b@http://localhost:8000/test.js:7:26
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: d
Trace:
d@http://localhost:8000/test.js:10:26
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: 
Trace:
a@http://localhost:8000/test.js:4:22
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: b
Trace:
b@http://localhost:8000/test.js:7:26
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: d
Trace:
d@http://localhost:8000/test.js:10:26
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: 
Trace:
i@http://localhost:8000/test.js:17:30
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: j
Trace:
j@http://localhost:8000/test.js:20:30
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: l
Trace:
l@http://localhost:8000/test.js:23:30
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: 
Trace:
http://localhost:8000/test.js:28:30
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: n
Trace:
n@http://localhost:8000/test.js:33:30
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: p
Trace:
p@http://localhost:8000/test.js:38:30
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

12

जावास्क्रिप्ट में कार्य करने के दो तरीके हैं:

  1. समारोह की घोषणा:

    function fn(){
      console.log("Hello");
    }
    fn();

    यह बहुत ही बुनियादी, आत्म-व्याख्यात्मक है, जिसका उपयोग कई भाषाओं में किया जाता है और भाषाओं के C परिवार में मानक है। हमने एक फ़ंक्शन को परिभाषित किया और इसे कॉल करके निष्पादित किया।

    आपको जो जानना चाहिए वह यह है कि फ़ंक्शन वास्तव में जावास्क्रिप्ट में ऑब्जेक्ट हैं; आंतरिक रूप से हमने उपरोक्त फ़ंक्शन के लिए एक ऑब्जेक्ट बनाया है और इसे fn नाम दिया है या ऑब्जेक्ट का संदर्भ fn में संग्रहीत है। कार्य जावास्क्रिप्ट में ऑब्जेक्ट हैं; कार्य का एक उदाहरण वास्तव में एक वस्तु उदाहरण है।

  2. समारोह अभिव्यक्ति:

    var fn=function(){
      console.log("Hello");
    }
    fn();

    जावास्क्रिप्ट में प्रथम श्रेणी के कार्य होते हैं, अर्थात्, एक फ़ंक्शन बनाते हैं और इसे एक चर पर असाइन करते हैं जैसे आप एक स्ट्रिंग या संख्या बनाते हैं और इसे एक चर पर असाइन करते हैं। यहाँ, fn वेरिएबल को एक फंक्शन में असाइन किया गया है। इस अवधारणा का कारण कार्य जावास्क्रिप्ट में ऑब्जेक्ट हैं; fn उपर्युक्त फ़ंक्शन के ऑब्जेक्ट उदाहरण की ओर इशारा कर रहा है। हमने एक फ़ंक्शन को इनिशियलाइज़ किया है और इसे एक वैरिएबल को असाइन किया है। यह फ़ंक्शन को निष्पादित नहीं कर रहा है और परिणाम असाइन कर रहा है।

संदर्भ: जावास्क्रिप्ट फ़ंक्शन घोषणा सिंटैक्स: var fn = function () {} बनाम फ़ंक्शन fn () {}


1
तीसरे विकल्प के बारे में क्या var fn = function fn() {...}?
छरवे

हाय छार्वे, उर सवाल के बारे में निश्चित नहीं है, मुझे लगता है कि उर फ़ंक्शन अभिव्यक्ति के बारे में बात कर रहा है जो मैंने पहले ही उल्लेख किया है। हालांकि, अगर अभी भी कुछ भ्रम है तो बस अधिक विस्तृत हो।
अनूप राय

हां मैं एक नामित कार्य अभिव्यक्ति के बारे में पूछ रहा था । यह आपके विकल्प # 2 के समान है सिवाय इसके कि फ़ंक्शन में एक पहचानकर्ता है। आमतौर पर यह पहचानकर्ता उस चर के समान होता है जिसे इसे सौंपा जा रहा है, लेकिन यह हमेशा ऐसा नहीं होता है।
छरई

1
हां नामांकित फ़ंक्शन अभिव्यक्ति मेरे विकल्प # 2 के समान है। वैसे एक पहचानकर्ता होना अनिवार्य नहीं है क्योंकि इसका उपयोग नहीं किया जाता है। जब भी आप फ़ंक्शन एक्सप्रेशन निष्पादित कर रहे होंगे, तो आप फ़ंक्शन ऑब्जेक्ट को पकड़े हुए वेरिएबल का उपयोग करेंगे। पहचानकर्ता कोई उद्देश्य नहीं रखता है।
अनूप राय

11

दोनों एक फ़ंक्शन को परिभाषित करने के विभिन्न तरीके हैं। अंतर यह है कि ब्राउज़र कैसे एक निष्पादन संदर्भ में व्याख्या करता है और उन्हें लोड करता है।

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

functionOne();
var functionOne = function() {
    // Some code
};

कारण यह है कि पहली पंक्ति में कोई भी फ़ंक्शन फ़ंक्शन को असाइन नहीं किया गया है, और इसलिए यह अपरिभाषित है। हम इसे एक फ़ंक्शन के रूप में कॉल करने का प्रयास कर रहे हैं, और इसलिए हमें एक त्रुटि मिल रही है।

दूसरी पंक्ति में हम एक अनाम फ़ंक्शन का संदर्भ कार्य कर रहे हैं।

दूसरा मामला फ़ंक्शन घोषणाओं का है जो किसी भी कोड को निष्पादित करने से पहले लोड करता है। इसलिए यदि आप निम्नलिखित को पसंद करते हैं तो आपको कोड निष्पादन से पहले घोषणा भार के रूप में कोई त्रुटि नहीं मिलेगी।

functionOne();
function functionOne() {
   // Some code
}

11

प्रदर्शन के बारे में:

नए संस्करणों V8ने कई अंडर-हूड अनुकूलन का परिचय दिया और ऐसा ही हुआ SpiderMonkey

अभिव्यक्ति और घोषणा के बीच अब लगभग कोई अंतर नहीं है।
फंक्शन एक्सप्रेशन अब और तेज़ होने लगता है

क्रोम 62.0.3202 क्रोम परीक्षण

फायरफॉक्स 55 फ़ायरफ़ॉक्स परीक्षण

क्रोम कैनरी 63.0.3225 क्रोम कैनरी परीक्षण


Anonymousफंक्शन एक्सप्रेशन से फंक्शन एक्सप्रेशन के खिलाफ बेहतर प्रदर्शनNamed होता है।


फ़ायरफ़ॉक्स क्रोम कैनरी क्रोमफ़ायरफ़ॉक्स नाम_अनाम Chrome कनारी नाम_अनाम Chrome नाम_अनाम


1
हां, यह अंतर इतना महत्वहीन है कि उम्मीद है कि देवता खुद चिंता करेंगे कि उनकी विशिष्ट आवश्यकताओं के लिए कौन सा दृष्टिकोण अधिक बनाए रखा जा सकता है जिसके बजाय कोई तेज हो सकता है (आपको ब्राउज़र क्या कर रहा है इसके आधार पर प्रत्येक प्रयास पर अलग-अलग jsperf परिणाम प्राप्त होंगे - जावास्क्रिप्ट कार्यों के बहुमत इस डिग्री के लिए सूक्ष्म अनुकूलन के साथ खुद को चिंता करने की जरूरत नहीं है)।
स्क्वीडबे

@squidbe कोई अंतर नहीं है। यहां देखें: jsperf.com/empty-tests-performance
जैक गिफिन

10

वे कुछ छोटे अंतरों के साथ बहुत समान हैं, पहला एक वैरिएबल है जिसे एक अनाम फ़ंक्शन (फंक्शन डिक्लेरेशन) को सौंपा गया है और दूसरा एक जावास्क्रिप्ट में एक फंक्शन बनाने का सामान्य तरीका है (बेनामी फंक्शन डिक्लेरेशन), दोनों में यूज़, कॉन्स और प्रोसीज़ होते हैं। :

1. समारोह अभिव्यक्ति

var functionOne = function() {
    // Some code
};

एक फंक्शन एक्सप्रेशन एक फ़ंक्शन को एक बड़ी अभिव्यक्ति सिंटैक्स (आमतौर पर एक चर असाइनमेंट) के एक भाग के रूप में परिभाषित करता है। फ़ंक्शंस एक्सप्रेशंस के माध्यम से परिभाषित फ़ंक्शंस का नाम या अनाम हो सकता है। समारोह अभिव्यक्तियाँ "फ़ंक्शन" से शुरू नहीं होनी चाहिए (इसलिए नीचे दिए गए स्वयं के उदाहरण के चारों ओर कोष्ठक)।

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

2. समारोह घोषणा

function functionTwo() {
    // Some code
}

एक फ़ंक्शन घोषणा चर नामकरण की आवश्यकता के बिना एक नामित फ़ंक्शन चर को परिभाषित करता है। फ़ंक्शन घोषणाएँ स्टैंडअलोन निर्माणों के रूप में होती हैं और गैर-फ़ंक्शन ब्लॉकों के भीतर नेस्टेड नहीं की जा सकती हैं। यह उन्हें परिवर्तनीय घोषणाओं के भाई-बहनों के रूप में सोचने में मददगार है। जैसे परिवर्तनीय घोषणाएँ "var" से शुरू होनी चाहिए, फ़ंक्शन घोषणाएँ "फ़ंक्शन" से शुरू होनी चाहिए।

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

इसके अलावा, यदि आपको जावास्क्रिप्ट में काम करने के बारे में अधिक जानकारी चाहिए, तो नीचे दिए गए लिंक पर जाएँ:

https://developer.mozilla.org/en-US/docs/Glossary/Hoisting


1
...also this way of declaring is a better way to create Constructor functions in JavaScript, क्या आप कृपया विस्तृत कर सकते हैं, मैं उत्सुक हूँ!
कार्ल मॉरिसन

एक कारण यह है कि जावास्क्रिप्ट में सभी अंतर्निहित कंस्ट्रक्टर फ़ंक्शन इस फ़ंक्शन संख्या () {[मूल कोड]} की तरह बनाए गए हैं और आपको अंतर्निहित लोगों के साथ भ्रमित नहीं होना चाहिए, इस मामले में बाद में भी संदर्भित करना सुरक्षित है और आप समाप्त करते हैं up neater कोड लेकिन उत्थापन का उपयोग नहीं ...
Alireza

8

यह फ़ंक्शन घोषित करने के केवल दो संभावित तरीके हैं, और दूसरे तरीके से, आप घोषणा से पहले फ़ंक्शन का उपयोग कर सकते हैं।


7

new Function()एक स्ट्रिंग में फ़ंक्शन के शरीर को पास करने के लिए उपयोग किया जा सकता है। और इसलिए इसका उपयोग गतिशील कार्यों को बनाने के लिए किया जा सकता है। स्क्रिप्ट को निष्पादित किए बिना भी स्क्रिप्ट पास करना।

var func = new Function("x", "y", "return x*y;");
function secondFunction(){
   var result;
   result = func(10,20);
   console.log ( result );
}

secondFunction()

हालांकि यह अच्छा और सच है, यह वास्तव में पूछे जाने वाले क्वाटिटोन से कैसे संबंधित है?
जैक गिफिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.