Var कीवर्ड का उद्देश्य क्या है और मुझे इसका उपयोग कब करना चाहिए (या इसे छोड़ना चाहिए)?


1543

नोट : यह सवाल ECMAScript संस्करण 3 या 5 के दृष्टिकोण से पूछा गया था। ECMAScript 6 की रिलीज़ में नई सुविधाओं की शुरुआत के साथ उत्तर पुराने हो सकते हैं।

varजावास्क्रिप्ट में कीवर्ड का कार्य वास्तव में क्या है और इसके बीच क्या अंतर है

var someNumber = 2;
var someFunction = function() { doSomething; }
var someObject = { }
var someObject.someProperty = 5;

तथा

someNumber = 2;
someFunction = function() { doSomething; }
someObject = { }
someObject.someProperty = 5;

?

आप कब एक का उपयोग करेंगे, और क्यों / क्या करता है?


3
जब var घोषणाओं का पीछा करते हैं, तो अल्पविराम के बाद व्यवहार को प्रभावित करने के लिए एक नई पंक्ति डालते हैं? var x = 1, y = 2, [वापसी] z = 3;
अल्फ़ाब्रावो

4
"Var" का उपयोग करने में विफल होने पर भी आप अपने द्वारा चुने गए वैरिएबल नाम को पहले से परिभाषित वैश्विक वैरिएबल होने पर छोड़ देते हैं। शोक की मेरी यात्रा यहाँ देखें: stackoverflow.com/questions/16704014/…
स्कॉट सी विल्सन

5
@Ray Toal के मेलनकार्ड ब्लॉग पोस्ट (निश्चित रूप से पढ़ने लायक) ब्लॉग पर स्थानांतरित हो गए हैं। safeshepherd.com/23/how-one-missing-var-ruined-our-launch
Hephaestus

मैंने कभी नहीं सोचा था कि एक कविता मुझे एक समस्याग्रस्त समस्या के लिए प्रेरित कर सकती है
फेलिक्स गगनोन-ग्रेनियर

1
@ गिबोल्ट लेकिन प्रश्न दिनांक को देखें, तो यह एक तरह से अनुचित है जो 2009 के प्रश्न को बताता है। हालांकि, यह अभी भी वैधता बनाए रखने की वर्तमान तिथि के रूप में मान्य है, वहाँ "आधुनिक जेएस" कोड का एक गुच्छा नहीं है।
आंद्रे फिग्यूएरेडो

जवाबों:


1355

यदि आप वैश्विक दायरे में हैं तो बहुत अंतर नहीं है। स्पष्टीकरण के लिए कंगैक्स का जवाब पढ़ें

यदि आप किसी फ़ंक्शन में हैं, तो varएक स्थानीय वैरिएबल बनाएगा, "कोई संस्करण" स्कोप श्रृंखला को तब तक नहीं देखेगा जब तक कि वह वैरिएबल को नहीं ढूंढता या हिट नहीं करता (जिस बिंदु पर वह इसे बनाएगा):

// These are both globals
var foo = 1;
bar = 2;

function()
{
    var foo = 1; // Local
    bar = 2;     // Global

    // Execute an anonymous function
    (function()
    {
        var wibble = 1; // Local
        foo = 2; // Inherits from scope above (creating a closure)
        moo = 3; // Global
    }())
}

यदि आप असाइनमेंट नहीं कर रहे हैं तो आपको उपयोग करने की आवश्यकता है var:

var x; // Declare x

31
क्या "वास्तव में बहुत अंतर नहीं है" == "कोई अंतर नहीं"?
एलेक्स

65
खैर, वास्तव में हाँ, वहाँ अंतर है :) क्या यह अंतर महत्वपूर्ण है एक और सवाल है। मेरे जवाब को और नीचे देखें: stackoverflow.com/questions/1470488/…
kangax

4
मुझे लगता है कि यह एलेक्स की बात हो सकती है, यही वजह है कि उन्होंने इसे "ऑपरेटर के बराबर" का उपयोग करके लिखा है!
जेम्स बेडफोर्ड

18
यह अपने आप को एक रेलगन के साथ शूट करने जैसा है ... किसी के वेरिएबल से पहले एक 'वेरिएंट' रखना भूल जाते हैं, और स्कोप चेन में कहीं एक वेरिएबल को मोडिफाई करते हैं ... किसी जावा / सी / पायथन / आदि को समझाने की कोशिश करें। डेवलपर जो जावास्क्रिप्ट योग्य है। हा! इसके विपरीत सी / सी ++ नुकसान अच्छा लगता है। कल्पना करें कि जावास्क्रिप्ट को डीबग करें ... और कुछ लोग निश्चित रूप से ऐसा करते हैं। और जावास्क्रिप्ट में इतना अधिक कोड (और सरल कोड, मन नहीं है) लिखा है ...
एल्बस डंबलडोर

6
यदि आप वैश्विक दायरे में हैं तो कोई अंतर नहीं है। >> वहाँ एक अंतर है जो नीचे दिए गए उत्तर में समझाया गया है
मैक्स कोरसेटस्की

746

एक अंतर है

var x = 1 xवर्तमान दायरे (उर्फ निष्पादन संदर्भ) में चर घोषित करता है । यदि एक फ़ंक्शन में घोषणा प्रकट होती है - एक स्थानीय चर घोषित किया जाता है; यदि यह वैश्विक दायरे में है - एक वैश्विक चर घोषित किया गया है।

x = 1दूसरी ओर, केवल एक संपत्ति असाइनमेंट है। यह पहले xगुंजाइश श्रृंखला के खिलाफ हल करने की कोशिश करता है । यदि यह उस दायरे की श्रृंखला में कहीं भी पाया जाता है, तो यह असाइनमेंट करता है; यदि यह नहीं मिलता है x, तो केवल यह xएक वैश्विक वस्तु पर संपत्ति बनाता है (जो एक गुंजाइश श्रृंखला में एक शीर्ष स्तर की वस्तु है)।

अब, ध्यान दें कि यह एक वैश्विक चर घोषित नहीं करता है, यह एक वैश्विक संपत्ति बनाता है।

दोनों के बीच का अंतर सूक्ष्म है और भ्रामक हो सकता है जब तक कि आप यह नहीं समझते कि परिवर्तनीय घोषणाएं भी (केवल एक चर वस्तु पर) गुण पैदा करती हैं और यह कि जावास्क्रिप्ट (अच्छी तरह से, ECMAScript) में प्रत्येक संपत्ति में कुछ झंडे होते हैं जो उनके गुणों का वर्णन करते हैं - Readlyly, DontEnum और DontDelete।

चूँकि परिवर्तनीय घोषणा DontDelete ध्वज के साथ संपत्ति बनाती है, ( var x = 1और x = 1जब वैश्विक दायरे में निष्पादित) के बीच का अंतर यह है कि पूर्व एक - चर घोषणा - DontDelete'able संपत्ति बनाता है, और बाद वाला नहीं करता है। परिणामस्वरूप, इस अंतर्निहित असाइनमेंट के माध्यम से बनाई गई संपत्ति को तब वैश्विक ऑब्जेक्ट से हटाया जा सकता है, और पूर्व एक - चर घोषणा के माध्यम से बनाया गया - हटाया नहीं जा सकता।

लेकिन यह सिर्फ पाठ्यक्रम का सिद्धांत है, और व्यवहार में दोनों के बीच और भी अधिक अंतर हैं , कार्यान्वयन में विभिन्न बगों के कारण (जैसे कि IE से)।

आशा है कि यह सब समझ में आता है:)


[अद्यतन 2010/12/16]

ES5 में (ECMAScript 5; हाल ही में मानकीकृत, भाषा का 5 वां संस्करण) एक तथाकथित "सख्त मोड" है - एक ऑप्ट-इन भाषा मोड, जो अघोषित असाइनमेंट के व्यवहार को थोड़ा बदल देता है। सख्त मोड में, अघोषित पहचानकर्ता को असाइनमेंट एक रेफरेंस है । इसके लिए तर्क यह था कि आकस्मिक कामों को पकड़ा जाए, अवांछित वैश्विक संपत्तियों के निर्माण को रोका जाए। कुछ नए ब्राउज़रों ने पहले से ही सख्त मोड के लिए समर्थन शुरू कर दिया है। उदाहरण के लिए, मेरी कंप्‍यूटर तालिका देखें


यदि मुझे सही ढंग से याद है, तो मुझे लगता है कि मुझे एक बार deleteकुछ evalहैक के साथ एक var-घोषित चर में सक्षम होने का एक तरीका मिला । अगर मुझे सटीक ट्रिक याद है तो मैं यहाँ पोस्ट करूँगा।
टॉवर

3
@ मागेक वह ऐसे निष्कासित घोषित चरों के बारे में ले रहा है जो हटाने योग्य हैं। मैंने एक बार इस बारे में एक ब्लॉग पोस्ट लिखा था ।
कंगैक्स

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

@ केंग्क्स क्या होगा अगर एलेक्स के उदाहरणों की अंतिम दो पंक्तियों को मिलाया गया: var someObject = {}और someObject.someProperty = 5? चाहेंगे someProperty, वैश्विक बन जबकि वस्तु यह अवशेषों की एक संपत्ति स्थानीय है?
Snapfractalpop

1
@ के लिए जो नाम डंकडेकेट ध्वज कहता है वह विन्यास योग्य है (= false) , आप इस बारे में पढ़ सकते हैं Object.definePropertyऔरObject.getOwnPropertyDescriptor
पॉल एस।

137

यह कहना कि " स्थानीय और वैश्विक " के बीच का अंतर पूरी तरह से सही नहीं है।

इसे " स्थानीय और निकटतम " के बीच का अंतर समझना बेहतर होगा । निकटतम निश्चित रूप से वैश्विक हो सकता है, लेकिन हमेशा ऐसा नहीं होगा।

/* global scope */
var local = true;
var global = true;

function outer() {
    /* local scope */
    var local = true;
    var global = false;

    /* nearest scope = outer */
    local = !global;

    function inner() {
        /* nearest scope = outer */
        local = false;
        global = false;

        /* nearest scope = undefined */
        /* defaults to defining a global */
        public = global;
    }
}

3
निकटतम गुंजाइश नहीं है outerजहाँ आप परिभाषित करते हैं var global = false;?
स्नेक

@Snekse: 'निकटतम' तब लागू नहीं होता जब <code> var global = false; </ code> घोषित किया जाता है। उस घोषणा में, 'वैश्विक' को बाहरी () के दायरे में रखा जाता है क्योंकि घोषणा में 'var' का उपयोग किया जाता है। क्योंकि भीतर () में 'var' का उपयोग नहीं किया गया है, यह अगले स्तर में मूल्य को बदल देगा, जो बाहरी है ()।
मिच

मुझे आश्चर्य है कि यदि आप टिप्पणी करते हैं कि यदि आप उस रेखा को बदल देते हैं तो var global = local;किस स्थिति में स्थानीय का निकट क्षेत्र "स्थानीय" बाहरी क्षेत्र होगा जो सक्रिय रूप से परिभाषित किया जा रहा है। हालांकि यह अजीब हो जाता है अगर आप उसी पंक्ति को बदलेंगे var global = global, जिस स्थिति में मूल्य की खोज करते समय निकटतम गुंजाइश globalवैश्विक खिड़की के दायरे में एक स्तर होगी।
स्नैच

80

जब जावास्क्रिप्ट को एक ब्राउज़र में निष्पादित किया जाता है, तो आपका सभी कोड विवरण के साथ घिरा होता है, जैसे:

with (window) {
    //Your code
}

अधिक जानकारी पर with- एमडीएन

चूंकि वर्तमान दायरे मेंvar एक चर घोषित किया जाता है , इसलिए खिड़की के अंदर घोषित करने और इसे बिल्कुल भी घोषित नहीं करने के बीच कोई अंतर नहीं है।var

अंतर तब आता है जब आप सीधे खिड़की के अंदर नहीं होते हैं, जैसे किसी फ़ंक्शन के अंदर या किसी ब्लॉक के अंदर।

उपयोग varकरने से आप बाहरी चरों को छिपा सकते हैं जिनका समान नाम है। इस तरह आप एक "निजी" चर का अनुकरण कर सकते हैं, लेकिन यह एक और विषय है।

अंगूठे का एक नियम हमेशा उपयोग करना है var, क्योंकि अन्यथा आप सूक्ष्म कीड़े को पेश करने का जोखिम चलाते हैं।

संपादित करें: मेरे द्वारा प्राप्त आलोचना के बाद, मैं निम्नलिखित पर जोर देना चाहूंगा:

  • varवर्तमान क्षेत्र में एक चर घोषित करता है
  • वैश्विक दायरा है window
  • ग्लोबल स्कोप (विंडो) में varस्पष्ट रूप से घोषणा का उपयोग नहीं करनाvar
  • वैश्विक स्कोप (विंडो) का उपयोग करके किसी वैरिएबल की घोषणा करना varइसे छोड़ने के समान है।
  • का उपयोग कर खिड़की से अलग scopes में एक चर की घोषणा के बिना एक चर घोषित करने के रूप में एक var ही बात नहीं हैvar
  • हमेशा varस्पष्ट रूप से घोषित करें क्योंकि यह अच्छा अभ्यास है

1
मैंने आपको निराश नहीं किया, लेकिन गुंजाइश शायद खिड़की से बेहतर शब्द है। आप पूरी व्याख्या कर रहे हैं थोड़ा सा obtuse है।
रॉबर्ट हार्वे

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

2
+1 यह एक बहुत अच्छी व्याख्या है - मैंने इससे पहले इस तरह के var / no var मुद्दे को फंसाया नहीं है (कोई भी इरादा नहीं)।
डग

इस उत्तर का अधिकांश भाग letES6 में दिया गया है।
इवान कैरोल

3
@EvanCarroll यह उत्तर तकनीकी रूप से भी गलत है क्योंकि ऑगिंग वर्जन किसी भी वैरिएबल की घोषणा नहीं करता है, इसके बजाय यह वैश्विक ऑब्जेक्ट पर एक हटाने योग्य संपत्ति बनाता है, इसके अलावा ES5 "सख्त उपयोग करें" मोड का जवाब के अधिकांश स्पष्ट रूप से सही नहीं है, यह भी नहीं है। इस उत्तर पर तब से भी विचार किया जाता है क्योंकि प्रश्न के समय में जावास्क्रिप्ट संस्करण (कल जोड़ा गया) का कोई संदर्भ नहीं था, जिसका अर्थ है कि संदर्भ का मानक (उस समय) ECMA 262 3rd संस्करण था।
kentaromiura

43

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

किसी भी चर के बिना बनाया var कीवर्ड वैश्विक स्कोप पर बनाया गया है और फ़ंक्शन के वापस आने पर कचरा एकत्र नहीं किया जाता है (क्योंकि यह स्कोप से बाहर नहीं जाता है), स्मृति रिसाव के लिए अवसर प्रस्तुत करता है।


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

@cao मुझे लगता good coding practiceहै कि हमेशा पर्याप्त कारण है अगर यह एक अनुशंसित सर्वोत्तम अभ्यास है, जो कि यह है और कई जावास्क्रिप्ट लेखकों द्वारा।
क्रिस एस

8
@ क्रिस: नहीं, "अच्छा कोडिंग अभ्यास" अपने आप में कारण नहीं है। इसका कारण यह माना जाता है कि अच्छा अभ्यास क्या मायने रखता है। जब तक कि वे लेखक आपको यह नहीं बताते हैं कि वे इसकी सिफारिश क्यों करते हैं, तो उनकी सिफारिश का कोई भार नहीं होना चाहिए। यदि आप कारणों से सहमत नहीं हैं, तो आप इसे बुरी सलाह मानने के लिए स्वतंत्र हैं। और अगर आप इसका पालन किए बिना कभी यह पूछते हैं कि, माल की खेती कैसे शुरू होती है।
cHao

30

यहाँ का एक अच्छा उदाहरण है कि आप स्थानीय चर घोषित नहीं करने से कैसे बाहर हो सकते हैं var:

<script>
one();

function one()
{
    for (i = 0;i < 10;i++)
    {
        two();
        alert(i);
    }
}

function two()
{
    i = 1;
}
</script>

( iलूप के प्रत्येक पुनरावृत्ति पर रीसेट किया जाता है, क्योंकि इसे स्थानीय रूप से forलूप में नहीं बल्कि वैश्विक रूप से घोषित किया जाता है ) जिसके परिणामस्वरूप अंततः लूप अनंत हो जाता है


ओह! मैं बस उन सभी बगों की कल्पना कर सकता हूं जो उस टाइपो के कारण हो सकते हैं।
बोनसाईऑक

2
मैं उत्सुक हूं, आप दो () के तर्क के रूप में क्यों गुजर रहे हैं? (लूप के अंदर) वह बेमानी है?
कलिन

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

बग या सुविधा?
23

13

मैं कहूंगा कि varज्यादातर स्थितियों में इसका इस्तेमाल करना बेहतर है।

वैश्विक दायरे में चर की तुलना में स्थानीय चर हमेशा तेज होते हैं।

यदि आप varएक चर घोषित करने के लिए उपयोग नहीं करते हैं , तो चर वैश्विक दायरे में होगा।

अधिक जानकारी के लिए, आप Google में "स्कोप चेन जावास्क्रिप्ट" खोज सकते हैं।


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

@ रय्यकपालन - अरे, क्या यह सच है? मैंने googling की कोशिश की और इस विषय पर कोई जानकारी नहीं प्राप्त कर सका! क्या आपके पास उस दावे के लिए एक स्रोत प्राधिकरण है? Thx
माइक कृंतक

@RyuKaplan पार्सिंग / संकलन वास्तव में कोड चलाने से अलग है।
gcampbell

11

उपयोग न करें var!

varचर घोषित करने का पूर्व-ईएस 6 तरीका था। हम अब भविष्य में हैं , और आपको इस तरह कोडिंग करनी चाहिए।

का उपयोग करें constऔरlet

const95% मामलों के लिए इस्तेमाल किया जाना चाहिए। यह बनाता है ताकि चर संदर्भ बदल नहीं सके, इस प्रकार सरणी, ऑब्जेक्ट और DOM नोड गुण बदल सकते हैं और होने की संभावना होनी चाहिए const

letपुन: असाइन किए जाने की अपेक्षा करने वाले किसी भी चर के लिए उपयोग किया जाना चाहिए। इसमें लूप के लिए शामिल है। यदि आप कभी भी varName =आरंभीकरण से परे लिखते हैं , तो उपयोग करें let

अधिकांश अन्य भाषाओं में अपेक्षा के अनुसार, दोनों में ब्लॉक स्तर की स्कूपिंग है।


2
आप सभी को 'var' को 'const' से बदलें (सभी को बदलें)। आप जल्दी से नोटिस करेंगे कि आपके पुन: असाइन किए गए चर कहां हैं। यदि आपके पास उनमें से बहुत सारे हैं, तो आप संभवतः विरोधी पैटर्न को कोड करते हैं: अधिकांश पुन: असाइन करने योग्य चर को बंद या ऑब्जेक्ट-गुणों के रूप में एम्बेड किया जा सकता है। यदि आपके पास कुछ है: उनके लिए 'लेट' का उपयोग करें। अंत में, अगर कुछ वैरिएबल जहां 'वर्जन ’के साथ बिल्कुल भी डिले नहीं होते हैं, तो वे अघोषित रहेंगे, और अभी भी ग्लोबल स्पेस में मौजूद हैं। @ लॉबट कमेंट 'फॉर ए फॉर लूप' के बारे में, "95% मामलों में" इस तरह के लूप से बचने की भी सिफारिश की जाती है; ;-): सरणी के तरीके बहुत अच्छे हैं।
एलीज एल'ओम

यह कहकर कि 95% मामलों में कास्ट का उपयोग किया जाना चाहिए, ऐसा लगता है कि हम अच्छे अभ्यास से दूर जा रहे हैं और हठधर्मिता में हैं।
अगामेन्नुस

9

एक और अंतर

var a = a || [] ; // works 

जबकि

a = a || [] ; // a is undefined error.

1
क्या आप बता सकते हैं कि यह 'var' के साथ परिभाषित चर के मामले में काम क्यों करता है और चर को var से परिभाषित नहीं किया जाता है? क्या वेरिएबल के मामले में असाइनमेंट के राइट साइड के मूल्यांकन से पहले बनाया गया है var?
मैट

6
@Lucek क्योंकि var aगुंजाइश के शीर्ष पर फहराया जाता है और अशक्त करने के लिए सेट किया जाता है जो घोषित करता है लेकिन चर को इनिशियलाइज़ नहीं करता है, तो असाइनमेंट में आपके पास एक अपरिभाषित अशक्त चर का संदर्भ है जो गलत का मूल्यांकन करता है, और असाइनमेंट सेट करता है []। उत्तरार्द्ध में, आपके पास संपत्ति aकी संपत्ति के लिए एक असाइनमेंट है a। आप ऐसी प्रॉपर्टी को असाइन कर सकते हैं जो मौजूद नहीं है - इसे असाइनमेंट पर बनाते हैं, लेकिन आप ऐसी प्रॉपर्टी से नहीं पढ़ सकते, ReferenceErrorजो आपके पास फेंके बिना नहीं रहती ।
इवान कैरोल

1
@ EvanCarroll: यह गुंजाइश के ऊपर फहराया जाता है और अशक्त के बजाय अपरिभाषित करने के लिए सेट हो जाता है।
मृत्युंजय

8

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


8

के बिना var - वैश्विक चर।

ALWAYS के उपयोग की दृढ़ता से सिफारिश की गई है var, क्योंकि स्थानीय संदर्भ में init वैश्विक चर - बुराई है। लेकिन, अगर आपको इस गंदी चाल की ज़रूरत है, तो आपको पृष्ठ के प्रारंभ में टिप्पणी लिखनी चाहिए:

/* global: varname1, varname2... */

3

यह उदाहरण कोड है जिसे मैंने आपके लिए इस अवधारणा को समझने के लिए लिखा है:

var foo = 5; 
bar = 2;     
fooba = 3;

// Execute an anonymous function
(function() {    
    bar = 100;             //overwrites global scope bar
    var foo = 4;           //a new foo variable is created in this' function's scope
    var fooba = 900;       //same as above
    document.write(foo);   //prints 4
    document.write(bar);   //prints 100
    document.write(fooba); //prints 900
})();

document.write('<br/>');
document.write('<br/>');
document.write(foo);       //prints 5
document.write(bar);       //prints 100
document.write(fooba);     //prints 3

2
फ़ंक्शन किसी भी तरह से "अनाम" नहीं है। वास्तव में, यह लगभग संभव के रूप में नामित के रूप में नाम के बारे में है।
इंगो बुर्क

Ingo Bürk की टिप्पणी के जवाब में अपना जवाब संपादित करने के लिए धन्यवाद, "अनाम फ़ंक्शन" को वास्तव में गुमनाम बनाने के लिए।
डेव बर्टन

3

@ क्रिस एस ने बीच varऔर नहीं में व्यावहारिक अंतर (और खतरे) को दिखाते हुए एक अच्छा उदाहरण दियाvar । यहां एक और है, मुझे यह एक विशेष रूप से खतरनाक लगता है क्योंकि अंतर केवल एक अतुल्यकालिक वातावरण में दिखाई देता है, इसलिए यह परीक्षण के दौरान आसानी से फिसल सकता है।

जैसा कि आप निम्नलिखित स्निपेट आउटपुट की अपेक्षा करेंगे ["text"]:

function var_fun() {
  let array = []
  array.push('text')
  return array
}

console.log(var_fun())

तो निम्नलिखित स्निपेट करता है ( letपहले लापता को नोट करें array):

function var_fun() {
  array = []
  array.push('text')
  return array
}

console.log(var_fun())

एसिंक्रोनस रूप से डेटा हेरफेर को निष्पादित करने के बाद भी एक ही निष्पादक के साथ एक ही परिणाम उत्पन्न होता है:

function var_fun() {
  array = [];
  return new Promise(resolve => resolve()).then(() => {
    array.push('text')
    return array
  })
}

var_fun().then(result => {console.log(result)})

लेकिन कई लोगों के साथ अलग तरह से व्यवहार करता है:

function var_fun() {
  array = [];
  return new Promise(resolve => resolve()).then(() => {
    array.push('text')
    return array
  })
}

[1,2,3].forEach(i => {
  var_fun().then(result => {console.log(result)})
})

फिर भी उपयोग कर रहे हैं:

function var_fun() {
  let array = [];
  return new Promise(resolve => resolve()).then(() => {
    array.push('text')
    return array
  })
}

[1,2,3].forEach(i => {
  var_fun().then(result => {console.log(result)})
})


उदाहरण @thisismydesign के लिए धन्यवाद! अंतिम दो उदाहरणों के संबंध में, प्रथागत उदाहरण पाठ लिखे तीन तत्वों की एक पंक्ति को तीन बार क्यों लिखते हैं जबकि अंतिम उदाहरण सरणी के भीतर प्रति तत्व केवल एक बार "पाठ" में प्रवेश करता है? (मैं समझता हूं कि अंतिम एक "सरणी" को एक चर के रूप में घोषित करता है और इसलिए स्थानीय दायरे में है, जबकि प्रचलित उदाहरण इसे छोड़ देता है, जिससे "सरणी" निहित वैश्विक दायरे का एक हिस्सा बन जाता है।) लेकिन, यह क्यों प्रभावित करता है। उत्पादन? क्या ऐसा इसलिए है क्योंकि forEach "i" फ़ंक्शन और सभी वैश्विक चर पर पुनरावृत्त करता है?
लगभग

2

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

यदि आप यह कोड चलाते हैं:

var local = true;
var global = true;


function test(){
  var local = false;
  var global = false;
  console.log(local)
  console.log(global)
}

test();

console.log(local);
console.log(global);

आउटपुट इस रूप में पढ़ेगा: असत्य, असत्य, सत्य, सत्य

क्योंकि यह फ़ंक्शन में चर को इसके बाहर से अलग के रूप में देखता है, इसलिए स्थानीय चर शब्द और इसका कारण यह था कि हमने असाइनमेंट में संस्करण का उपयोग किया था। यदि आप फंक्शन में var को हटाते हैं तो यह अब इस तरह से पढ़ता है:

var local = true;
var global = true;


function test(){
  local = false;
  global = false;
  console.log(local)
  console.log(global)
}

test();

console.log(local);
console.log(global);

आउटपुट झूठा है, झूठा है, झूठा है, झूठा है

ऐसा इसलिए है क्योंकि स्थानीय दायरे या फ़ंक्शन में एक नया चर बनाने के बजाय यह केवल वैश्विक चर का उपयोग करता है और उन्हें गलत तरीके से पुन: असाइन करता है।


2

मैं जब साथ या बिना चर घोषित करने को देखने के लोगों को भ्रमित कर रहे हैं वर और अंदर या बाहर कार्य करते हैं। यहाँ एक गहरा उदाहरण दिया गया है जो आपको इन चरणों से गुजारेगा:

नीचे दी गई स्क्रिप्ट को jsfiddle पर देखें

a = 1;// Defined outside the function without var
var b = 1;// Defined outside the function with var
alert("Starting outside of all functions... \n \n a, b defined but c, d not defined yet: \n a:" + a + "\n b:" + b + "\n \n (If I try to show the value of the undefined c or d, console.log would throw 'Uncaught ReferenceError: c is not defined' error and script would stop running!)");

function testVar1(){
    c = 1;// Defined inside the function without var
    var d = 1;// Defined inside the function with var
    alert("Now inside the 1. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);

    a = a + 5;
    b = b + 5;
    c = c + 5;
    d = d + 5;

    alert("After added values inside the 1. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);
};


testVar1();
alert("Run the 1. function again...");
testVar1();

function testVar2(){
    var d = 1;// Defined inside the function with var
    alert("Now inside the 2. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);

    a = a + 5;
    b = b + 5;
    c = c + 5;
    d = d + 5;

    alert("After added values inside the 2. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);
};

testVar2();

alert("Now outside of all functions... \n \n Final Values: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n You will not be able to see d here because then the value is requested, console.log would throw error 'Uncaught ReferenceError: d is not defined' and script would stop. \n ");
alert("**************\n Conclusion \n ************** \n \n 1. No matter declared with or without var (like a, b) if they get their value outside the function, they will preserve their value and also any other values that are added inside various functions through the script are preserved.\n 2. If the variable is declared without var inside a function (like c), it will act like the previous rule, it will preserve its value across all functions from now on. Either it got its first value in function testVar1() it still preserves the value and get additional value in function testVar2() \n 3. If the variable is declared with var inside a function only (like d in testVar1 or testVar2) it will will be undefined whenever the function ends. So it will be temporary variable in a function.");
alert("Now check console.log for the error when value d is requested next:");
alert(d);

निष्कर्ष

  1. किसी भी प्रकार के साथ या बिना संस्करण के बिना घोषित (जैसे, बी) यदि वे फ़ंक्शन के बाहर अपना मूल्य प्राप्त करते हैं, तो वे अपने मूल्य को संरक्षित करेंगे और स्क्रिप्ट के माध्यम से विभिन्न कार्यों के अंदर जोड़े गए किसी भी अन्य मान संरक्षित हैं।
  2. यदि किसी फ़ंक्शन (जैसे c) के अंदर वेरिएबल के बिना वेरिएबल घोषित किया जाता है, तो यह पिछले नियम की तरह कार्य करेगा, यह अब से सभी फ़ंक्शन के लिए अपने मूल्य को संरक्षित करेगा। या तो इसे फ़ंक्शन testVar1 में पहला मान मिला () यह अभी भी मान को संरक्षित रखता है और फ़ंक्शन testV2 () में अतिरिक्त मान प्राप्त करता है
  3. यदि किसी फ़ंक्शन के अंदर वेरिएबल केवल वेरिएंट के साथ घोषित किया जाता है (जैसे कि testVar1 या testVar2 में d) तो फ़ंक्शन समाप्त होने पर इसे अपरिभाषित किया जाएगा। तो यह एक फ़ंक्शन में अस्थायी चर होगा।

इस विषय को प्रदर्शित करने के लिए एक उदाहरण बनाने के लिए समय निकालने के लिए धन्यवाद। ऊपर दिया गया कोड नीचे का भाग गायब है, इसलिए आप अपना उत्तर संपादित करना चाहते हैं: a = 1; // बिना var var b = 1 फ़ंक्शन के बाहर परिभाषित; // var अलर्ट के साथ फ़ंक्शन के बाहर परिभाषित ("सभी फ़ंक्शन के बाहर शुरू करना") ... \ n \ n, b परिभाषित लेकिन c, d अभी तक परिभाषित नहीं: \ n: "+ a +" \ nb: "+ b +" \ n \ n (यदि मैं अपरिभाषित c का मान दिखाने का प्रयास करता हूं या डी, कंसोल.लॉग फेंक देंगे 'अनट्रेक्टेड संदर्भ: सी को परिभाषित नहीं किया गया है' त्रुटि और स्क्रिप्ट बंद हो जाएगी;) ");
सांक्यो

1

किसी कोड के अंदर यदि आप बिना वेरिएबल का उपयोग किए एक चर का उपयोग करते हैं, तो क्या होता है स्वचालित रूप से var_name को वैश्विक दायरे में रखा जाता है जैसे:

someFunction() {
    var a = some_value; /*a has local scope and it cannot be accessed when this
    function is not active*/
    b = a; /*here it places "var b" at top of script i.e. gives b global scope or
    uses already defined global variable b */
}

1

स्कोप्स के मुद्दे के अलावा, कुछ लोगों ने फहराने का भी उल्लेख किया , लेकिन किसी ने भी एक उदाहरण नहीं दिया। यहाँ वैश्विक गुंजाइश के लिए एक है:

console.log(noErrorCase);
var noErrorCase = "you will reach that point";

console.log(runTimeError);
runTimeError = "you won't reach that point";


0

"Var" वेरिएबल्स का उपयोग किए बिना केवल एक मान सेट करते समय परिभाषित कर सकते हैं। उदाहरण में:

my_var;

वैश्विक दायरे या किसी अन्य दायरे में काम नहीं कर सकता । यह मान के साथ होना चाहिए:

my_var = "value";

दूसरी ओर आप एक जीवंत को परिभाषित कर सकते हैं जैसे;

var my_var;

इसका मान है undefined(इसका मान नहीं है nullऔर यह nullदिलचस्प नहीं के बराबर है ।)।


my_var;वास्तव में एक वैध अभिव्यक्ति कथन है।
lexicore

यह वैरिएबल स्टेटमेंट है यदि वेरिएबल को पहले परिभाषित किया गया है। अन्यथा यह एक त्रुटि "... परिभाषित नहीं है"।
umut

3
यह एक मान्य कथन है, भले ही एक चर को पहले परिभाषित किया गया हो या नहीं। :) एक वैध बयान एक उतारा फेंक सकता है जो बयान को अमान्य नहीं बनाता है ।
lexicore

मैं इसे लेकर उलझन में हूं। मान्य कथन क्या है? और क्या आप मुझे एक अमान्य बयान उदाहरण दे सकते हैं?
--मुत

मुझे माफी माँगनी पड़ेगी - हाल ही में बहुत अधिक ECMAScript व्याकरण। my_var;एक मान्य अभिव्यक्ति कथन है/my_var;अमान्य कथन होगा। लेकिन जैसा कि मैंने कहा, यह व्याकरण के मामले हैं, मैं माफी मांगता हूं, मेरी टिप्पणी वास्तव में उचित नहीं थी।
15

0

जब तक आप ब्राउज़र में विंडो ऑब्जेक्ट से जुड़े वैरिएबल का इरादा नहीं रखते तब तक आपको var कीवर्ड का उपयोग करना चाहिए। यहां एक लिंक दिया गया है जो स्कूपिंग और ग्लोकल स्कूपिंग और स्थानीय स्कॉपिंग के बीच अंतर और wihtout var कीवर्ड के बारे में बताता है।

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

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

तुम भी जावास्क्रिप्ट में उत्थापन देखना चाहते हो सकता है

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