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




keyword ecmascript-5 (16)

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

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

तो, संक्षेप में, हमेशा var कीवर्ड का उपयोग करके चर घोषित करें।

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

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

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

तथा

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

?

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


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

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

/* 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;
    }
}

मैं लोगों को उलझन में या बिना अंदर और अंदर या बाहर चर के घोषित करते समय उलझन में हूं। यहां एक गहरा उदाहरण है जो आपको इन चरणों के माध्यम से चलाएगा:

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. कोई फर्क नहीं पड़ता कि var के साथ या बिना var (जैसे, बी) यदि उन्हें फ़ंक्शन के बाहर अपना मूल्य मिलता है, तो वे उनके मान को सुरक्षित रखेंगे और स्क्रिप्ट के माध्यम से विभिन्न कार्यों के अंदर जोड़े गए किसी भी अन्य मान को संरक्षित किया जाएगा।
  2. यदि परिवर्तनीय को किसी फ़ंक्शन (जैसे सी) के अंदर var के बिना घोषित किया गया है, तो यह पिछले नियम की तरह कार्य करेगा, यह अब से सभी कार्यों में अपना मूल्य सुरक्षित रखेगा। या तो इसे फ़ंक्शन testVar1 () में अपना पहला मान मिला है, यह अभी भी मान को संरक्षित करता है और फ़ंक्शन testVar2 () में अतिरिक्त मान प्राप्त करता है
  3. यदि चर केवल एक फ़ंक्शन के अंदर var के साथ घोषित किया गया है (जैसे testVar1 या testVar2 में डी) यह कार्य समाप्त होने पर अपरिभाषित होगा। तो यह एक समारोह में अस्थायी चर होगा।

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

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

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

with (window) {
    //Your code
}

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

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

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

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

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

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

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

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

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

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

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

<script>
one();

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

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

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


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

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

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

आप जावास्क्रिप्ट में hoisting देखना भी चाह सकते हैं


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

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

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 को हटाते हैं तो अब यह इस तरह पढ़ता है:

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

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

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


एक अंतर है

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

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

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

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

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

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

उम्मीद है कि यह सब समझ में आता है:)

[अपडेट 2010/12/16]

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


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

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

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

console.log(var_fun())

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

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


यदि आप वैश्विक दायरे में हैं तो कोई फर्क नहीं पड़ता।

यदि आप एक फ़ंक्शन में हैं तो var एक स्थानीय चर बना देगा, "नो 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

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

my_var;

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

my_var = "value";

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

var my_var;

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


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


एक और अंतर उदाहरण के लिए

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

जबकि

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

Lombok var का समर्थन करता है लेकिन यह अभी भी प्रयोगात्मक के रूप में वर्गीकृत है:

import lombok.experimental.var;

var number = 1; // Inferred type: int
number = 2; // Legal reassign since var is not final
number = "Hi"; // Compilation error since a string cannot be assigned to an int variable
System.out.println(number);

IntelliJ IDEA में इसका उपयोग करने का प्रयास करते समय बचने के लिए Here एक गड़बड़ी है। ऐसा लगता है कि ऑटो पूर्णता और सब कुछ शामिल है। जब तक "गैर-हैकी" समाधान नहीं होता है (उदाहरण के लिए openjdk.java.net/jeps/286 ), यह अभी आपका सबसे अच्छा शर्त हो सकता है।

ध्यान दें कि lombok.config किया गया है, साथ ही lombok.config को संशोधित या बनाने के बिना।





javascript keyword ecmascript-5