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




syntax idioms (20)

gives an example where he names an assigned function to be able to use shortcut() as an internal reference to itself. John Resig gives another example - copying a recursive function assigned to another object in his Learning Advanced Javascript tutorial. While assigning functions to properties isn't strictly the question here, I recommend actively trying the tutorial out - run the code by clicking the button in the upper right corner, and double click the code to edit to your liking.

Examples from the tutorial: recursive calls in yell() :

Tests fail when the original ninja object is removed. (page 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?" ); 
}

If you name the function that will be called recursively, the tests will pass. (page 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." );

https://code.i-harness.com

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

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

दो तरीके हैं:

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

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


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

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

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

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

और, एक समारोह घोषणा:

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

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

इसका मतलब यह भी है कि आप फ़ंक्शन घोषणाओं का उपयोग करके फ़ंक्शंस को सशर्त रूप से परिभाषित नहीं कर सकते हैं:

if (test) {
   // Error or misbehavior
   function functionThree() { doSomething(); }
}

उपर्युक्त वास्तव में functionThree को परिभाषित करता है test के मूल्य के बावजूद - जब तक use strict प्रभावी नहीं होता है, इस मामले में यह केवल एक त्रुटि उठाता है।


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

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

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

ऐसा इसलिए है क्योंकि पहले संस्करण के साथ, कार्य रन टाइम पर परिवर्तनीय foo को सौंपा गया है। दूसरे में, कार्य उस पहचानकर्ता, foo , पार्स समय पर असाइन किया गया है।

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

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

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

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

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

}

या

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

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

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


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

शर्तें:

त्वरित सूची:

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

  • "बेनामी" 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 तक, कल्पना में शामिल नहीं था कि जावास्क्रिप्ट इंजन को क्या करना चाहिए यदि आप नियंत्रण संरचना के अंदर फ़ंक्शन घोषणा जैसे try , if , switch , इत्यादि, जैसे:

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');
};

सभी अभिव्यक्तियों की तरह, यह मूल्यांकन किया जाता है जब यह कोड के चरण-दर-चरण निष्पादन में पहुंच जाता है।

ईएस 5 में, इस रचना के फ़ंक्शन का कोई नाम नहीं है (यह अनाम है)। ES2015 में, फ़ंक्शन को संदर्भ से संदर्भित करके संभवतः एक नाम असाइन किया गया है। उपर्युक्त उदाहरण में, नाम y होगा। कुछ ऐसा ही किया जाता है जब फ़ंक्शन किसी प्रॉपर्टी प्रारंभकर्ता का मान होता है। (यह कब होता है और नियमों के विवरण के लिए , विनिर्देशन में SetFunctionName खोज करें - यह पूरे स्थान पर दिखाई देता है।)

नामित function अभिव्यक्ति

तीसरा रूप एक नामित फ़ंक्शन अभिव्यक्ति ("एनएफई") है:

var z = function w() {
    console.log('zw')
};

इस रचना का कार्य उचित नाम है (इस मामले में w )। सभी अभिव्यक्तियों की तरह, यह मूल्यांकन किया जाता है जब यह कोड के चरण-दर-चरण निष्पादन में पहुंच जाता है। फ़ंक्शन का नाम उस दायरे में नहीं जोड़ा गया है जिसमें अभिव्यक्ति प्रकट होती है; नाम फ़ंक्शन के भीतर ही दायरे में है:

var z = function w() {
    console.log(typeof w); // "function"
};
console.log(typeof w);     // "undefined"

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

एक्सेसर फ़ंक्शन प्रारंभकर्ता (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.defineProperties लिए कम ज्ञात दूसरे तर्क के साथ Object.defineProperty फ़ंक्शंस भी बना सकते हैं।

तीर फंक्शन अभिव्यक्ति (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() में छिपा रही है map() कॉल? यह एक समारोह है।

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

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

  2. जैसा कि आपने उपरोक्त के साथ देखा होगा, आप कीवर्ड function उपयोग नहीं करते हैं; इसके बजाय, आप => उपयोग करते हैं।

ऊपर n => n * 2 उदाहरण उनमें से एक रूप है। यदि आपके पास फ़ंक्शन पास करने के लिए कई तर्क हैं, तो आप माता-पिता का उपयोग करते हैं:

var a = [1, 2, 3];
var b = a.map((n, i) => n * i);
console.log(b.join(", ")); // 0, 2, 6

(याद रखें कि Array#map प्रवेश को पहले तर्क के रूप में पास करता है, और सूचकांक दूसरे के रूप में।)

दोनों मामलों में, समारोह का शरीर सिर्फ एक अभिव्यक्ति है; फ़ंक्शन का रिटर्न वैल्यू स्वचालित रूप से उस अभिव्यक्ति का परिणाम होगा (आप एक स्पष्ट return उपयोग नहीं करते 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() {
    }
};

ईएस 5 और पहले के बराबर होगा:

var o = {
    foo: function foo() {
    }
};

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 को सौंपा गया एक फ़ंक्शन है।


वैश्विक संदर्भ के बारे में बोलते हुए, दोनों तरफ var कथन और एक FunctionDeclaration घोषणा वैश्विक वस्तु पर एक गैर-हटाने योग्य संपत्ति बनायेगी , लेकिन दोनों का मूल्य ओवरराइट किया जा सकता है

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

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

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

फ़ंक्शनक्लेक्लेरेशन द्वारा बनाई गई एक वैश्विक प्रॉपर्टी को किसी वैरिएबल वैल्यू की तरह किसी भी समस्या के बिना अधिलेखित किया जा सकता है, उदाहरण के लिए:

 function test () {}
 test = null;

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

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

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

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

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

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


new Function() can be used to pass the function's body in a string. And hence this can be used to create dynamic functions. Also passing the script without executing the script.

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

secondFunction()

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

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

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

Variable

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

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';
}
  • पृष्ठ के अंदर घोषित कार्यों को वैश्विक पहुंच वाले पृष्ठ के शीर्ष पर रखा गया है।
  • फंक्शन-ब्लॉक के अंदर घोषित कार्यों को ब्लॉक के शीर्ष पर फेंक दिया जाता है।
  • फ़ंक्शन का डिफ़ॉल्ट वापसी मान ' undefined ' है, Variable घोषणा डिफ़ॉल्ट मान भी 'अपरिभाषित'

    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 का उपयोग कर विभिन्न ब्राउज़र के फ़ंक्शन घोषणा, अभिव्यक्ति परीक्षण की जांच कर सकते हैं

ईएस 5 कन्स्ट्रक्टर फंक्शन क्लासेस : फंक्शन ऑब्जेक्ट्स फंक्शन.प्रोटोटाइप.बिंड का उपयोग करके बनाया गया

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

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 introduced Arrow function : An arrow function expression has a shorter syntax, they are best suited for non-method functions, and they cannot be used as constructors.

ArrowFunction : ArrowParameters => ConciseBody .

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

A function declaration and a function expression assigned to a variable behave the same once the binding is established.

There is a difference however at how and when the function object is actually associated with its variable. This difference is due to the mechanism called variable hoisting in JavaScript.

Basically, all function declarations and variable declarations are hoisted to the top of the function in which the declaration occurs (this is why we say that JavaScript has function scope ).

  • When a function declaration is hoisted, the function body "follows" so when the function body is evaluated, the variable will immediately be bound to a function object.

  • When a variable declaration is hoisted, the initialization does not follow, but is "left behind". The variable is initialized to undefined at the start of the function body, and will be assigned a value at its original location in the code. (Actually, it will be assigned a value at every location where a declaration of a variable with the same name occurs.)

The order of hoisting is also important: function declarations take precedence over variable declarations with the same name, and the last function declaration takes precedence over previous function declarations with the same name.

Some examples...

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

Variable foo is hoisted to the top of the function, initialized to undefined , so that !foo is true , so foo is assigned 10 . The foo outside of bar 's scope plays no role and is untouched.

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 declarations take precedence over variable declarations, and the last function declaration "sticks".

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

In this example a is initialized with the function object resulting from evaluating the second function declaration, and then is assigned 4 .

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

Here the function declaration is hoisted first, declaring and initializing variable a . Next, this variable is assigned 10 . In other words: the assignment does not assign to outer variable a .


Another difference that is not mentioned in the other answers is that if you use the anonymous function

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

and use that as a constructor as in

var one = new functionOne();

then one.constructor.name will not be defined. Function.name is non-standard but is supported by Firefox, Chrome, other Webkit-derived browsers and IE 9+.

With

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

it is possible to retrieve the name of the constructor as a string with two.constructor.name .


Greg's Answer is good enough, but I still would like to add something to it that I learned just now watching Douglas Crockford's videos.

Function expression:

var foo = function foo() {};

Function statement:

function foo() {};

The function statement is just a shorthand for var statement with a function value.

इसलिए

function foo() {};

expands to

var foo = function foo() {};

Which expands further to:

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

And they are both hoisted to the top of the code.


I use the variable approach in my code for a very specific reason, the theory of which has been covered in an abstract way above, but an example might help some people like me, with limited JavaScript expertise.

I have code that I need to run with 160 independently-designed brandings. Most of the code is in shared files, but branding-specific stuff is in a separate file, one for each branding.

Some brandings require specific functions, and some do not. Sometimes I have to add new functions to do new branding-specific things. I am happy to change the shared coded, but I don't want to have to change all 160 sets of branding files.

By using the variable syntax, I can declare the variable (a function pointer essentially) in the shared code and either assign a trivial stub function, or set to null.

The one or two brandings that need a specific implementation of the function can then define their version of the function and assign this to the variable if they want, and the rest do nothing. I can test for a null function before I execute it in the shared code.

From people's comments above, I gather it may be possible to redefine a static function too, but I think the variable solution is nice and clear.


I'm listing out the differences below:

  1. A function declaration can be placed anywhere in the code. Even if it is invoked before the definition appears in code, it gets executed as function declaration is committed to memory or in a way it is hoisted up, before any other code in the page starts execution.

    Take a look at the function below:

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

    This is because, during execution, it looks like:-

    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
    

    A function expression, if not defined before calling it, will result in an error. Also, here the function definition itself is not moved to the top or committed to memory like in the function declarations. But the variable to which we assign the function gets hoisted up and undefined gets assigned to it.

    Same function using function expressions:

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

    This is because during execution, it looks like:

    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. It is not safe to write function declarations in non-function blocks like if because they won't be accessible.

    if (test) {
        function x() { doSomething(); }
    }
    
  3. Named function expression like the one below, may not work in Internet Explorer browsers prior to version 9.

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

If you would use those functions to create objects, you would get:

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

In computer science terms, we talk about anonymous functions and named functions. I think the most important difference is that an anonymous function is not bound to an name, hence the name anonymous function. In JavaScript it is a first class object dynamically declared at runtime.

For more information on anonymous functions and lambda calculus, Wikipedia is a good start ( http://en.wikipedia.org/wiki/Anonymous_function ).


In light of the "named functions show up in stack traces" argument, modern JavaScript engines are actually quite capable of representing anonymous functions.

As of this writing, V8, SpiderMonkey, Chakra and Nitro always refer to named functions by their names. They almost always refer to an anonymous function by its identifier if it has one.

SpiderMonkey can figure out the name of an anonymous function returned from another function. The rest can't.

If you really, really wanted your iterator and success callbacks to show up in the trace, you could name those too...

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

But for the most part it's not worth stressing over.

Harness ( Fiddle )

'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'));

V8

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

SpiderMonkey

func.name: 
Trace:
[email protected]://localhost:8000/test.js:4:5
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


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


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


func.name: 
Trace:
[email protected]://localhost:8000/test.js:4:5
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


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


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


func.name: 
Trace:
[email protected]://localhost:8000/test.js:17:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


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


func.name: l
Trace:
[email protected]://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:
[email protected]://localhost:8000/test.js:33:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


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

Chakra

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)

Nitro

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

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

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

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

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

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

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

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

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

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

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

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

The first example is a function declaration:

function abc(){}

The second example is a function expression:

var abc = function() {};

The main difference is how they are hoisted (lifted and declared). In the first example, the whole function declaration is hoisted. In the second example only the var 'abc' is hoisted, its value (the function) will be undefined, and the function itself remains at the position that it is declared.

To put it simply:

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

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

To study more about this topic I strongly recommend you this link


The first one (function doSomething(x)) should be part of an object notation.

The second one ( var doSomething = function(x){ alert(x);} ) is simply creating an anonymous function and assigning it to a variable, doSomething . So doSomething() will call the function.

You may want to know what a function declaration and function expression is.

A function declaration defines a named function variable without requiring variable assignment. Function declarations occur as standalone constructs and cannot be nested within non-function blocks.

function foo() {
    return 3;
}

ECMA 5 (13.0) defines the syntax as
function Identifier ( FormalParameterList opt ) { FunctionBody }

In above condition the function name is visible within its scope and the scope of its parent (otherwise it would be unreachable).

And in a function expression

A function expression defines a function as a part of a larger expression syntax (typically a variable assignment ). Functions defined via functions expressions can be named or anonymous. Function expressions should not start with “function”.

// 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) defines the syntax as
function Identifier opt ( FormalParameterList opt ) { FunctionBody }


They are pretty similar with some small differences, first one is a variable which assigned to an anonymous function (Function Declaration) and second one is the normal way to create a function in JavaScript(Anonymous function Declaration), both has usage, cons and pros:

1. Function Expression

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

A Function Expression defines a function as a part of a larger expression syntax (typically a variable assignment ). Functions defined via Functions Expressions can be named or anonymous. Function Expressions must not start with “function” (hence the parentheses around the self invoking example below).

Assign a variable to a function, means no Hoisting, as we know functions in JavaScript can Hoist, means they can be called before they get declared, while variables need to be declared before getting access to them, so means in this case we can not access the function before where it's declared, also it could be a way that you write your functions, for the functions which return another function, this kind of declaration could make sense, also in ECMA6 & above you can assign this to an arrow function which can be used to call anonymous functions, also this way of declaring is a better way to create Constructor functions in JavaScript.

2. Function Declaration

function functionTwo() {
    // Some code
}

A Function Declaration defines a named function variable without requiring variable assignment. Function Declarations occur as standalone constructs and cannot be nested within non-function blocks. It's helpful to think of them as siblings of Variable Declarations. Just as Variable Declarations must start with “var”, Function Declarations must begin with “function”.

This is the normal way of calling a function in JavaScript, this function can be called before you even declare it as in JavaScript all functions get Hoisted, but if you have 'use strict' this won't Hoist as expected, it's a good way to call all normal functions which are not big in lines and neither are a constructor function.

Also, if you need more info about how hoisting works in JavaScript, visit the link below:

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


This is just two possible ways of declaring functions, and in the second way, you can use the function before declaration.





idioms