जावास्क्रिप्ट समारोह scoping और उत्थापन


90

मैं बेन चेरी द्वारा जावास्क्रिप्ट स्कोपिंग और उत्थापन के बारे में एक महान लेख पढ़ता हूं जिसमें वह निम्नलिखित उदाहरण देता है:

var a = 1;

function b() {
    a = 10;
    return;

    function a() {}
}
b();
alert(a);

उपरोक्त कोड का उपयोग करके, ब्राउज़र "1" को अलर्ट करेगा।

मैं अभी भी अनिश्चित हूं कि यह "1" क्यों लौटाता है। उनके द्वारा कही गई कुछ बातें मन में आती हैं जैसे: समारोह की सभी घोषणाएँ ऊपर की ओर फहराई जाती हैं। आप फ़ंक्शन का उपयोग करके एक चर को स्कोप कर सकते हैं। फिर भी मेरे लिए क्लिक नहीं करता।

जवाबों:


120

फंक्शन उत्थापन का अर्थ है कि फ़ंक्शन को उनके दायरे के शीर्ष पर ले जाया गया है। अर्थात्,

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

इसके लिए इंटरपीटर द्वारा फिर से लिखा जाएगा

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

अजीब, एह?

इस उदाहरण में,

function a() {}

जैसा व्यवहार किया

var a = function () {};

तो, संक्षेप में, यह वही है जो कोड कर रहा है:

var a = 1;                 //defines "a" in global scope
function b() {  
   var a = function () {}; //defines "a" in local scope 
   a = 10;                 //overwrites local variable "a"
   return;      
}       
b();       
alert(a);                 //alerts global variable "a"

2
तो सभी फ़ंक्शन घोषणाएं अंततः एक चर को सौंपी जाती हैं?
dev.e.loper

15
@ dev.e.loper हाँ, जावास्क्रिप्ट में, फ़ंक्शंस और संख्याओं की तरह फ़ंक्शंस प्रथम श्रेणी के ऑब्जेक्ट हैं। इसका मतलब है कि उन्हें चर के रूप में परिभाषित किया गया है और अन्य कार्यों के लिए पारित किया जा सकता है, सरणियों में संग्रहीत किया जा सकता है, और इसी तरह।
पीटर ओल्सन

4
किसी भी तरह से फ़ंक्शन बॉडी "पुनर्लेखन" नहीं है। विभिन्न ECMAScript मानकों में स्पष्ट रूप से कहा गया है कि कोड निष्पादन शुरू होने से पहले चर और फ़ंक्शन घोषणाओं को संसाधित किया जाता है। यही है, कुछ भी नहीं ले जाया जाता है , यह निष्पादन के आदेश के बारे में है (इसलिए "उत्थापन" शब्द के प्रति मेरी नापसंदगी, जो आंदोलन या पुनर्व्यवस्था को प्रभावित करता है)। आपके पुन: लिखे गए कोड में, डिक्लेरेशन var aफंक्शन डिक्लेरेशन से पहले होना चाहिए, और असाइनमेंट के a = 1बाद होना चाहिए। लेकिन ध्यान दें कि यह वास्तव में पार्सर, टोकन, इंटरप्रेटर, कंपाइलर, जो कुछ भी हो, द्वारा निर्दिष्ट नहीं है , यह सिर्फ एक समतुल्य है।
RobG

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

7
"इसके अलावा, इस उदाहरण में, function a() {}समान व्यवहार किया गया है var a = function () {};"  - यह दो तरह से गलत है: पहला, अगर कुछ भी, यह होता है var a = function a() {};(फ़ंक्शन वास्तव में अनाम नहीं है), दूसरा, वे दो रूप विनिमेय नहीं हैं, क्योंकि से var a = function a() {};केवल var a;हिस्सा फहराया गया होगा। a = function a() {};हिस्सा अभी भी वापसी कथन के पीछे हो गया होता। क्योंकि मूल रूप एक फ़ंक्शन घोषणा है और फ़ंक्शन अभिव्यक्ति नहीं है, यह वास्तव में पूरे के रूप में फहराया जाता है।
user4642212

6

आपको जो याद रखना है वह यह है कि यह पूरे फ़ंक्शन को पार्स करता है और इसे निष्पादित करने से पहले सभी चर घोषणाओं को हल करता है। इसलिए....

function a() {} 

वास्तव में बन जाता है

var a = function () {}

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


5

समारोह के aअंदर फहराया जाता है b:

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

जो लगभग उपयोग की तरह है var:

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

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


1
यह रेखा "var a = function () {};" हर बात को स्पष्ट करती है .. मूल रूप से JavaScript डायनामिक लैंग्वेज है और "function" भी जावास्क्रिप्ट में एक ऑब्जेक्ट है।
रिफ्लेक्टर

3
  1. फंक्शन डिक्लेरेशन function a(){}पहले फहराया जाता है और यह व्यवहार करता है var a = function () {};, इसलिए स्थानीय स्कोप aबनाया जाता है।
  2. यदि आपके पास एक ही नाम के साथ दो चर हैं (स्थानीय में एक अन्य वैश्विक में), स्थानीय चर हमेशा वैश्विक चर पर पूर्वता प्राप्त करते हैं।
  3. जब आप सेट a=10करते हैं, तो आप स्थानीय वैरिएबल सेट कर रहे हैं a, वैश्विक नहीं।

इसलिए, वैश्विक वैरिएबल का मूल्य समान रहता है और आपको 1 अलर्ट मिलता है


1

function a() { }एक फ़ंक्शन स्टेटमेंट है, जो फ़ंक्शन के aलिए एक चर स्थानीय बनाता है b
किसी फ़ंक्शन को पार्स किए जाने पर वेरिएबल्स बनाए जाते हैं, भले ही varफ़ंक्शन फ़ंक्शन को निष्पादित किया जाए या नहीं ।

a = 10 यह स्थानीय चर सेट करता है।


वास्तव a = 10में वैश्विक दायरे में एक चर सेट करता है जब फ़ंक्शन bको निष्पादित किया जाता है जब तक कि आप "use strict"(ऐसे वातावरण में जो निर्देश का समर्थन करते हैं) जोड़ते हैं ।
सीन विएरा

@ सीन: नहीं, क्योंकि फ़ंक्शन स्टेटमेंट एक स्थानीय पहचानकर्ता बनाता है।
SLaks

... और .... आप सही कह रहे हैं। फंक्शन उत्थापन के उस विशेष परिणाम का एहसास नहीं हुआ था। धन्यवाद!
सीन विएरा

1

कोड के इस छोटे स्निपेट में विवाद की हड्डी क्या है?

मामला एक:

निम्नानुसार function a(){}शरीर के अंदर परिभाषा को शामिल करें function blogs value of a = 1

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

  function a() {}
}
b();
console.log(a); // logs a = 1

केस 2

निम्नानुसार function a(){}शरीर के अंदर की परिभाषा को छोड़ दें function blogs value of a = 10

var a = 1;
function b() {
  a = 10;  // overwrites the value of global 'var a'
  return;
}
b();
console.log(a); // logs a = 10

अवलोकन आपको यह महसूस करने में मदद करेगा कि कथन console.log(a)निम्नलिखित मानों को लॉग करता है।

केस 1: ए = 1

केस 2: ए = 10

मानती

  1. var a वैश्विक दायरे में परिभाषित और घोषित रूप से किया गया है।
  2. a=10 यह कथन 10 के मान को पुन: असाइन कर रहा है, यह lexically फ़ंक्शन बी के अंदर बैठता है।

दोनों मामलों की व्याख्या

function definition with name propertyक की वजह से समान है variable avariable aअंदर function body bएक स्थानीय चर हो जाता है। पिछली पंक्ति का तात्पर्य है कि अवशेषों का वैश्विक मूल्य और एक का स्थानीय मूल्य 10 पर अपडेट किया गया है।

तो, हम जो कहना चाहते हैं, वह है नीचे का कोड

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

  function a() {}
}
b();
console.log(a); // logs a = 1

इसकी व्याख्या जेएस दुभाषिया द्वारा की गई है।

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


}
b();
console.log(a); // logs a = 1

हालाँकि, जब हम फ़ंक्शन बी के बाहर घोषित और परिभाषित function a(){} definitionको हटाते हैं , तो value of 'a'वह मान अधिलेखित हो जाता है और यह 10 में बदल जाता है। 2. मान ओवरराइट हो जाता है क्योंकि a=10वैश्विक घोषणा को संदर्भित करता है और यदि इसे स्थानीय रूप से घोषित किया जाना चाहिए तो हमारे पास होना चाहिए। लिखा है var a = 10;

var a = 1;
function b() {
  var a = 10; // here var a is declared and defined locally because it uses a var keyword. 
  return;
}
b();
console.log(a); // logs a = 1

हम अपने संदेह को किसी अन्य नाम name propertyमें बदलकर आगे स्पष्ट कर सकते हैंfunction a(){} definition'a'

var a = 1;
function b() {
  a = 10; // here var a is declared and defined locally because it uses a var keyword. 
  return;

  function foo() {}
}
b();
console.log(a); // logs a = 1

1

उत्थापन एक अवधारणा है जिसे समझना हमारे लिए आसान है। वास्तव में क्या होता है घोषणाएं पहले उनके स्कोप के संबंध में की जाती हैं और असाइनमेंट उसके बाद होंगे (उसी समय नहीं)।

जब घोषणाएं होती हैं, var aतब, function bउस bदायरे के अंदर , function aघोषित किया जाता है।

यह कार्य वैश्विक दायरे से आने वाले चर को छाया देगा।

घोषणाएं पूरी होने के बाद, जो मान असाइन किए गए हैं, वे शुरू हो जाएंगे, वैश्विक aको मूल्य मिलेगा 1और एक को अंदर function bमिलेगा 10। जब आप ऐसा alert(a)करेंगे, तो यह वास्तविक वैश्विक स्कोप वैरिएबल कहलाएगा। कोड में यह थोड़ा सा बदलाव इसे और अधिक स्पष्ट कर देगा

        var a = 1;

    function b() {
        a = 10;
        return a;

        function a() { }
    }

    alert(b());
    alert(a);

1
यह उत्सुक है कि इतने सारे विशेषज्ञ भी codechool.com पर एक पाठ्यक्रम में उत्थापन को संदर्भित करते हैं जो कि क्या होता है के एक सरलीकृत दृष्टिकोण से ज्यादा कुछ नहीं है, वास्तव में उत्थापन बिल्कुल भी नहीं होता है। Ref: 1) developer.mozilla.org/en-US/docs/Glossary/Hoisting 2) जावास्क्रिप्ट निंजा 2 / e के रहस्य का अध्याय 5 john resig, bebeault, josip maras
adnan2nd

1

आश्चर्यजनक रूप से, यहां कोई भी उत्तर स्कोप श्रृंखला में निष्पादन संदर्भ की प्रासंगिकता का उल्लेख नहीं करता है।

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

मैं नीचे दिए गए उदाहरण का उपयोग प्रदर्शन के रूप में करूंगा।

1) सबसे पहले, हम वैश्विक निष्पादन संदर्भ के निर्माण चरण में प्रवेश करते हैं। लेक्सिकल एनवायरनमेंट के आउटर एनवायर्नमेंटल और वैरिएबल एनवायरनमेंट दोनों ही बनते हैं। ग्लोबल ऑब्जेक्ट को सेटअप किया गया है और विशेष चर के साथ मेमोरी में रखा गया है। समारोह और उसके कोड और अपरिभाषित मूल्य के साथ चर myVar को वैश्विक परिवर्तनीय वातावरण में स्मृति में रखा जाता है। यह ध्यान रखना महत्वपूर्ण है कि फ़ंक्शन का कोड निष्पादित नहीं किया गया है। यह सिर्फ समारोह ए के साथ स्मृति में रखा गया है।

2) दूसरा, यह निष्पादन के संदर्भ का निष्पादन चरण है। myVar अब एक अपरिभाषित मान नहीं है। इसे 1 के मूल्य के साथ आरंभीकृत किया जाता है, जिसे वैश्विक परिवर्तनीय पर्यावरण में संग्रहीत किया जाता है। फ़ंक्शन को लागू किया जाता है और एक नया निष्पादन संदर्भ बनाया जाता है।

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

4) फ़ंक्शन b को फ़ंक्शन में लाया जाता है a। एक नया निष्पादन संदर्भ बनाया गया है। चूंकि यह फंक्शन में लेक्सिकली बैठता है, इसलिए इसका आउटर एनवायरनमेंट एक है। इसलिए जब यह myVar का संदर्भ देता है, क्योंकि myVar फ़ंक्शन b के वैरिएबल एनवायरनमेंट में नहीं है, यह फंक्शन के Variable Environment में दिखेगा। यह वहाँ पाता है और कंसोल.लॉग प्रिंट्स 2. लेकिन अगर वेरिएबल फ़ंक्शन के वैरिएबल एनवायरनमेंट में नहीं था, तो चूंकि फंक्शन ए का आउटर एनवायर्नमेंटल एक्ज़ीक्यूटिव कॉनटेक्स्ट है, तो स्कोप चेन वहां सर्च करना जारी रखेगा।

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

function a(){
  function b(){
    console.log(myVar);
  }

  var myVar = 2;
  b();
}

var myVar = 1;
a();
b();
> 2
> Uncaught ReferenceError: b is not defined

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

function a(){
  function b(){
    console.log(myVar);
  }

  b();
}

var myVar = 1;
a();
> 1

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


0

यह वैरिएबल नाम के कारण हो रहा है क्योंकि फ़ंक्शन नाम का अर्थ "a" है। इस प्रकार जावास्क्रिप्ट उत्थापन के कारण यह नामकरण संघर्ष को हल करने की कोशिश करता है और यह एक = 1 वापस आ जाएगा।

मैं इस बारे में तब तक उलझन में था जब तक मैंने इस पोस्ट को "जावास्क्रिप्ट उत्थापन" http://www.ufthelp.com/2014/11/JavaScript-Histing.html पर नहीं पढ़ा

आशा करता हूँ की ये काम करेगा।


0

यहाँ और अधिक एनोटेशन और एक acompaniying फिडेल के साथ उत्तर के बारे में मेरे पुनरावृत्ति के साथ खेलने के लिए है।

// hoisting_example.js

// top of scope ie. global var a = 1
var a = 1;

// new scope due to js' functional (not block) level scope
function b() {
    a = 10; // if the function 'a' didn't exist in this scope, global a = 10
  return; // the return illustrates that function 'a' is hoisted to top
  function a(){}; // 'a' will be hoisted to top as var a = function(){};
}

// exec 'b' and you would expect to see a = 10 in subsequent alert
// but the interpreter acutally 'hoisted' the function 'a' within 'b' 
// and in doing so, created a new named variable 'a' 
// which is a function within b's scope
b();

// a will alert 1, see comment above
alert(a);

https://jsfiddle.net/adjavaherian/fffpxjx7/


0

स्कोप और क्लोजर और उत्थापन (var / function)

  1. scpope: वैश्विक संस्करण को किसी भी स्थान (संपूर्ण फ़ाइल स्कोप) में एक्सेस किया जा सकता है, स्थानीय संस्करण को केवल स्थानीय स्कोप (फ़ंक्शन / ब्लॉक स्कोप) द्वारा एक्सेस किया जा सकता है!
    नोट: यदि कोई स्थानीय वैरिएबल फ़ंक्शन में वैर कीवर्ड का उपयोग नहीं करता है, तो यह एक ग्लोबल वैरिएबल बन जाएगा!
  2. क्लोजर: एक फंक्शन दूसरे फंक्शन को इनर करता है, जो लोकल स्कोप (पैरेंट फंक्शन) और ग्लोबल स्कोप को एक्सेस कर सकता है, हॉवर यह वर्जन दूसरों के द्वारा एक्सेस नहीं किया जा सकता है! जब तक, आपका रिटर्न इसे रिटर्न वैल्यू के रूप में नहीं देता है!
  3. उत्थापन: मान या अशक्त असाइन करने की अपेक्षा, सभी घोषित / अचयनित vars / फ़ंक्शन को स्कोप टॉप में ले जाएँ!
    नोट: यह सिर्फ घोषणा को स्थानांतरित करता है, मूल्य को स्थानांतरित नहीं करता है!

var a = 1;                
//"a" is global scope
function b() {  
   var a = function () {}; 
   //"a" is local scope 
   var x = 12; 
   //"x" is local scope 
   a = 10;
   //global variable "a" was overwrited by the local variable "a"  
   console.log("local a =" + a);
   return console.log("local x = " + x);
}       
b();
// local a =10
// local x = 12
console.log("global a = " + a);
// global a = 1
console.log("can't access local x = \n");
// can't access local x = 
console.log(x);
// ReferenceError: x is not defined



0

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


0

यह सब चर 'a' के दायरे पर निर्भर करता है। मुझे चित्र के रूप में स्कोप बनाकर समझाएं।

यहां जावास्क्रिप्ट 3 स्कोप बनाएगी।

i) ग्लोबल स्कोप। ii) फंक्शन b () स्कोप। iii) फ़ंक्शन () स्कोप।

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

इसकी स्पष्टता यह है कि जब आप 'अलर्ट' विधि का दायरा उस समय के ग्लोबल का होता है, तो यह वैरिएबल 'ए' के ​​वैरिएबल वैल्यू को केवल 1 पर ले जाएगा।


0

लंबी पोस्ट!

लेकिन यह हवा को साफ करेगा!

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

  1. संकलन (इसलिए बोलने के लिए) - यह चरण चर और फ़ंक्शन घोषणाओं और उनके संबंधित दायरे को पंजीकृत करता है। यह मूल्यांकन कर समारोह अभिव्यक्ति को शामिल नहीं करता: var a = function(){}(बताए की तरह या चर अभिव्यक्ति 3के xमामले में की var x =3;। जो कुछ भी नहीं लेकिन आरएचएस भाग के मूल्यांकन है)

  2. दुभाषिया: यह निष्पादन / मूल्यांकन हिस्सा है।

समझ पाने के लिए नीचे दिए गए कोड के आउटपुट की जाँच करें:

//b() can be called here!
//c() cannot be called.
console.log("a is " + a);
console.log("b is " + b);
console.log("c is " + c);
var a = 1;
console.log("Now, a is " + a);
var c = function() {};
console.log("Now c is " + c);

function b() {
  //cannot write the below line:
  //console.log(e); 
  //since e is not declared.
  e = 10; //Java script interpreter after traversing from this function scope chain to global scope, is unable to find this variable and eventually initialises it with value 10 in global scope.
  console.log("e is " + e) //  works!
  console.log("f is " + f);
  var f = 7;
  console.log("Now f is " + f);
  console.log("d is " + d);
  return;

  function d() {}
}
b();
console.log(a);

इसे तोड़ें:

  1. संकलन चरण में, 'a' को वैश्विक दायरे में मूल्य के साथ पंजीकृत किया जाएगा undefined'। समान ' c' के लिए जाता है , इस समय इसका मूल्य ' undefined' नहीं ' function()' होगा। ' b' वैश्विक दायरे में एक समारोह के रूप में पंजीकृत किया जाएगा। अंदर bका दायरा, ' f' को एक चर के रूप में पंजीकृत किया जाएगा जो इस समय अपरिभाषित होगा और फ़ंक्शन ' d' पंजीकृत किया जाएगा।

  2. जब दुभाषिया चलता है, function()तो वास्तविक अभिव्यक्ति रेखा तक पहुंचने से पहले , घोषित चर और (और अभिव्यक्ति नहीं) पहुँचा जा सकता है। इसलिए, चर को 'मुद्रित' किया जाएगा undefinedऔर घोषित अनाम फ़ंक्शन को पहले बुलाया जा सकता है। हालाँकि, इसकी अभिव्यक्ति आरंभीकरण से पहले अघोषित चर का उपयोग करने की कोशिश करने के परिणामस्वरूप त्रुटि होगी:

console.log(e)
e = 3;

अब, जब आपके पास चर और फ़ंक्शन समान नाम के साथ घोषित होते हैं, तो क्या होता है।

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

var a = 1;
console.log("a is " + a);

function b() {
  console.log("a inside the function b is " + a); //interpreter finds                                'a' as function() in current scope. No need to go outside the scope to find 'a'.
  a = 3; //a changed
  console.log("Now a is " + a);
  return;

  function a() {}
}
var a; //treated as duplicate and ignored.
b();
console.log("a is still " + a + " in global scope"); //This is global scope a.


0

उत्थापन जावास्क्रिप्ट की व्यवहार संबंधी अवधारणा है। उत्थापन (कहना चाल) वह अवधारणा है जो बताती है कि कैसे और कहाँ चर घोषित किए जाने चाहिए।

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

हम ज्यादातर मामलों में दो प्रकार के उत्थापन का सामना करते हैं।

1. परिवर्तनीय घोषणा उत्थापन

कोड के इस टुकड़े से इसे समझते हैं।

 a = 5; // Assign 5 to a
 elem = document.getElementById("demo"); // Find an element 
 elem.innerHTML = a;                     // Display a in the element
 var a; // Declare a
  //output-> 5

यहाँ चर की घोषणा को संकलन के समय जावास्क्रिप्ट इंटरप्रेटर द्वारा अदृश्य रूप से शीर्ष पर होस्ट किया जाएगा। इसलिए हम मूल्य प्राप्त करने में सक्षम थे। लेकिन चरों की घोषणा के इस दृष्टिकोण की अनुशंसा नहीं की जाती है क्योंकि हमें चरों की घोषणा पहले ही कर देनी चाहिए।

 var a = 5; // Assign and declare 5 to a
 elem = document.getElementById("demo"); // Find an element 
 elem.innerHTML = a;                     // Display a in the element
  // output -> 5

एक और उदाहरण पर विचार करें।

  function foo() {
     console.log(x)
     var x = 1;
 }

वास्तव में इस तरह व्याख्या की है:

  function foo() {
     var x;
     console.log(x)
     x = 1;
  }

इस स्थिति में x अपरिभाषित होगा

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

  function foo() {
     if (false) {
         var a = 1;
     }
     return;
     var b = 1;
  }

यह कार्य इस तरह से होता है।

  function foo() {
      var a, b;
      if (false) {
        a = 1;
     }
     return;
     b = 1;
  }

चर घोषणा में केवल चर परिभाषा लहराती है, असाइनमेंट नहीं।

  1. फंक्शन घोषणा फहराना

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

 function demo() {
     foo(); // this will give error because it is variable hoisting
     bar(); // "this will run!" as it is function hoisting
     var foo = function () {
         alert("this would not run!!");
     }
     function bar() { 
         alert("this will run!!");
     }
 }
 demo();

अब जैसा कि हम दोनों परिवर्तनशील और फ़ंक्शन को फहरा रहे हैं, आइए अब इस कोड को समझते हैं।

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

यह कोड इस तरह से निकलेगा।

var a = 1;                 //defines "a" in global scope
 function b() {  
   var a = function () {}; //defines "a" in local scope 
    a = 10;                 //overwrites local variable "a"
    return;      
 }       
 b();       
 alert(a); 

फ़ंक्शन a () में b () के अंदर स्थानीय स्कोप होगा। a () को इसकी परिभाषा के साथ कोड की व्याख्या करते हुए शीर्ष पर ले जाया जाएगा (केवल फ़ंक्शन उत्थापन के मामले में) इसलिए अब इसमें स्थानीय गुंजाइश होगी और इसलिए फ़ंक्शन बी के अंदर अपना स्वयं का दायरा होने के दौरान वैश्विक स्तर को प्रभावित नहीं करेगा () ।


0

मेरे ज्ञान के टुकड़े से, उत्थापन परिवर्तनशील घोषणा और कार्य घोषणा के साथ होता है, उदाहरण के लिए:

a = 7;
var a;
console.log(a) 

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

var a;
a = 7;
console.log(a);
// 7

या:

console.log(square(7)); // Output: 49
function square(n) { return n * n; }

यह हो जाएगा:

function square(n) { return n * n; }
console.log(square(7)); // 49

लेकिन वेरिएबल असिग्मेंट, फंक्शन एक्सप्रेशन असाइनमेंट जैसे असाइनमेंट फहराए नहीं जाएंगे: उदाहरण के लिए:

console.log(x);
var x = 7; // undefined

यह इस तरह बन सकता है:

var x;
console.log(x); // undefined
x = 7;

0

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

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

मैं मान रहा हूं कि आप एक शुरुआती हैं, ठीक से समझने के लिए पहले हमने अपरिभाषित और संदर्भ संदर्भ के बीच के अंतर को समझा है।

 var v;
 console.log(v);
 console.log(abc);
/*
The output of the above codes are:
undefined
ReferenceError: abc is not defined*/

अब bellow कोड में हम क्या देखते हैं? एक चर और एक समारोह अभिव्यक्ति स्पष्ट है।

<script>
var totalAmo = 8;
var getSum = function(a, b){
      return a+b;
}
</script>

लेकिन इस प्रमाण के साथ असली तस्वीर कि दोनों चर और फ़ंक्शन दोनों को ऊपर के दायरे में फहराया गया है:

console.log(totalAmo);
console.log(getSum(8,9));
var totalAmo = 8;
var getSum = function(a, b){
      return a+b;
}
console.log(totalAmo);
console.log(getSum(9,7));

पहले दो लॉग का आउटपुट अपरिभाषित है और TypeError: getSum एक फ़ंक्शन नहीं है क्योंकि दोनों संस्करण varAmo हैं और getSum को उनके दायरे के शीर्ष पर फहराया जाता है जैसे कि bellow

 <script>
        var totalAmo;
        var getSum;

        console.log(totalAmo);
        console.log(getSum(8,9));
        var totalAmo = 8;
        var getSum = function(a, b){
            return a+b;
        }
        console.log(totalAmo);
        console.log(getSum(9,7));
    </script>

लेकिन कार्यों की घोषणा के लिए पूरे कार्य अपने दायरे के शीर्ष पर फहराए गए।

console.log(getId());
function getId(){
   return 739373;
}
/* output: 739373, because the whole function hoisted on the top of the scope.*/

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

function functionScope(){
            var totalAmo;
            var getSum;

            console.log(totalAmo);
            console.log(getSum(8,9));
            var totalAmo = 8;
            var getSum = function(a, b){
                return a+b;
            }
        }

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

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

 function getTotal(){
            let total=0;
            for(var i = 0; i<10; i++){
                let valueToAdd = i;
                var multiplier = 2;
                total += valueToAdd*multiplier;
            }
            return total;
        }

एब्बो उदाहरण में चर को बोले की तरह फहराया जाएगा

 function getTotal(){
            let total;
            var multiplier;
            total = 0;
            for(var i = 0; i<10; i++){
                let valueToAdd;
                valueToAdd = i;
                multiplier = 2;
                total += valueToAdd*multiplier;
            }
            return total;
        }

0

ES5: फहराने और परिवर्तनशील फहराने का कार्य

function hoistingप्राथमिकता से greaterहैvariable hoisting

"use strict";

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @created 2016-06-01
 * @modified
 *
 * @description function-hoisting.js
 * @augments
 * @example
 * @link
 *
 */

(function() {
  const log = console.log;

  var a = 1;
  function b() {
    a = 10;
    log(`local a`, a)
    return;
    // function hoisting priority is greater than variable hoisting
    function a() {}
  }
  b();
  log(`global a`, a);
  // local a 10
  // global a 1
})();



जो के बराबर है

(function() {
  const log = console.log;

  // define "a" in global scope
  var a = 1;
  function b() {
    // define "a" in local scope
    var a ;
    // assign function to a
    a = function () {};
    // overwrites local variable "a"
    a = 10;
    log(`local a`, a);
    return;
  }

  b();
  // log global variable "a"
  log(`global a`, a);

  // local a 10
  // global a 1
})();

फहराने के पीछे का कारण

var a = 1;                
//"a" is global scope
function b() {  
   var a = function () {}; 
   //"a" is local scope 
   var x = 12; 
   //"x" is local scope 
   a = 10;
   //global variable "a" was overwrited by the local variable "a"  
   console.log("local a =" + a);
   return console.log("local x = " + x);
}       
b();
// local a =10
// local x = 12
console.log("global a = " + a);
// global a = 1
console.log("can't access local x = \n");
// can't access local x = 
console.log(x);
// ReferenceError: x is not defined

/**
 *  scpope & closure & hoisting (var/function)
 *  
 * 1. scpope : the global var can be access in any place(the whole file scope), local var only can be accessed by the local scope(function/block scope)!
 * Note: if a local variable not using var keywords in a function, it will become a global variable!
 * 
 * 2. closure : a function inner the other function, which can access local scope(parent function) & global scope, howerver it's vars can't be accessed by others! unless, your return it as return value!
 * 
 * 3. hoisting : move all declare/undeclare vars/function to the scope top, than assign the value or null!
 * Note: it just move the declare, not move the value!
 * 
 */

ES6 let, constकोई अस्तित्व नहीं है

(() => {
  const log = console.log;
  log(a)
  // Error: Uncaught ReferenceError: Cannot access 'a' before initialization
  let a = 1;
})();



(() => {
  const log = console.log;
  log(b)
  // Error: Uncaught ReferenceError: Cannot access 'b' before initialization
  const b = 1;
})();

refs

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const

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