ES6 में "var" कीवर्ड का उपयोग करने का कोई कारण है?


260

ईएस 6 को बाबेल का मार्गदर्शक कहता है:

letनया है var

जाहिरा तौर पर एकमात्र अंतर यह है कि varवर्तमान फ़ंक्शन केlet लिए स्कोप हो जाता है , जबकि वर्तमान ब्लॉक में स्कोप हो जाता है । इस उत्तर में कुछ अच्छे उदाहरण हैं ।

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

इसलिए मेरी वृत्ति varES6 कोड लिखते समय पूरी तरह से उपयोग बंद करना है ।

मेरा सवाल यह है कि क्या मैं इस बारे में गलत हूं? क्या कोई वैध मामला है जहां varबेहतर होगा let?


3
मैंने अभी तक यह कोशिश नहीं की है (क्योंकि मैं अभी तक ES6 कोड नहीं लिख रहा हूं), लेकिन ऐसा लगता है कि varएक सचेत संकेतक के रूप में उपयोग करना है कि इस चर का उद्देश्य पूरे फ़ंक्शन के लिए स्कूप किया जाना एक उपयोगी "स्व-दस्तावेजीकरण" सम्मेलन हो सकता है ।
२०

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

11
ईमानदारी से, मेरा मानना ​​है कि एकमात्र कारण varअभी भी मौजूद है, पीछे-संगतता है। यदि यह उस के लिए नहीं थे, तो वे varपूरी तरह से हटा दिए गए थे, या letपहले स्थान पर कभी भी पेश नहीं किए गए थे, बजाय इसके varकि यह सब क्या होना चाहिए था के अर्थ को बदलकर ।
जोर्ज डब्ल्यू मित्तग

2
@RayToal मैं काइल सिम्पसन के 97% से सहमत हूं, लेकिन उनका उपयोग करते रहने के कारण varमुझे पतले लगते हैं, और तीसरे प्रकार के चर के वारंट के लिए पर्याप्त नहीं है जो चारों ओर कूदता है। आप इसे letफंक्शन में सबसे ऊपर रखकर पूरे फंक्शन को स्कोप कर सकते हैं , जो कि varकिसी ब्लॉक में लिखने के इरादे से ज्यादा साफ होता है (ताकि उस ब्लॉक से बाहर फहराया जा सके ताकि आप ब्लॉक के बाहर इस्तेमाल कर सकें। - अजीब)। वह चेतावनी देते हैं कि यदि आप letकिसी फ़ंक्शन को स्कोप करते हैं तो "यह सिर्फ़ पोज़िशन है जो सिंटैक्स के बजाय अंतर को इंगित करता है", लेकिन मुझे लगता है कि यह एक अच्छी बात है।
कॉलम

2
@RayToal मैंने भी वह लेख पढ़ा (इस चर्चा को पढ़ने से ठीक पहले) और मैं वास्तव में उसके बहुत कमजोर मामले के लिए निराश था var। जिन उदाहरणों को वह रखने के लिए प्रस्तुत करता है वे varआकस्मिक प्रतीत होते हैं - और गंभीर कोडिंग त्रुटियों पर आधारित हैं। यह एक त्रुटि में चलाने के लिए बेहतर है और भाषा के कार्यों का उपयोग करने के लिए ऐसी त्रुटियों को ठीक करने के लिए मजबूर किया जाना चाहिए जो किसी को इसके साथ दूर जाने दें! आगे क्या है, दुर्घटनाओं को रोकने के लिए एक कोशिश / पकड़ने में सब कुछ लपेटने की सलाह देते हैं? उस लिंक का बाकी हिस्सा अच्छा है लेकिन मैं उस विशेष भाग से बिल्कुल सहमत नहीं हूं।
मोरे

जवाबों:


217

डग क्रॉकफोर्ड ने अपनी बात " द बेटर पार्ट्स " letमें इस बिंदु पर चर्चा की ।

मुद्दा यह है, letगलतफहमी, esp के स्रोत से बचा जाता है। ब्लॉक-स्कोप वाली भाषाओं द्वारा निर्धारित अपेक्षाओं वाले प्रोग्रामर के लिए। A varमें फंक्शन स्कोप है (यह फंक्शन में दिखाई देने वाला वैरिएबल घोषित करता है) भले ही ऐसा लगता है कि इसमें ब्लॉक स्कोप है

var संभवतः मशीन-जनरेटेड कोड जैसे किसी चरम मामले में भी उपयोगी हो सकता है, लेकिन मैं वहां कड़ी मेहनत कर रहा हूं।

( constयह भी नया है और इसमें ब्लॉक स्कोप है। इसके बाद let x = {'hi': 'SE'}आप इसे फिर से असाइन कर सकते हैं x, जबकि इसके बाद const y = xआप इसे फिर से असाइन नहीं कर सकते y। यह अक्सर बेहतर होता है क्योंकि यह गलती से आपके नीचे से कुछ बदल रहा है। लेकिन स्पष्ट होने के लिए, आप तब भी ऑब्जेक्ट को संशोधित कर सकते हैं y.hi = 'SO'जब तक कि आप तब तक। इसे फ्रीज करें।)

यथार्थवादी रूप से, आपका प्रभाव ES6: Adopt और के लिए सही है का उपयोग बंद करो letconstvar

( "द बेटर पार्ट्स" के एक अन्य प्रदर्शन में , डौग कहते हैं कि समस्याओं को=== ठीक करने के== बजाय क्यों जोड़ा गया । ==कुछ "आश्चर्यजनक" परिणाम पैदा करता है, इसलिए बस अपनाएं ===।)


एक खुलासा उदाहरण

मोज़िला डेवलपर नेटवर्क एक उदाहरण देता है जहां varइरादा नहीं है। उनका उदाहरण एक यथार्थवादी है जो onclickवेब पेज में हैंडलर सेट करता है । यहाँ एक छोटा परीक्षण मामला है:

var a = [];
(function () {
   'use strict';
   for (let i = 0; i < 5; ++i) { // *** `let` works as expected ***
     a.push( function() {return i;} );
   }
} ());
console.log(a.map( function(f) {return f();} ));
// prints [0, 1, 2, 3, 4]

// Start over, but change `let` to `var`.
// prints [5, 5, 5, 5, 5]

varहमें विफल कर देता है क्योंकि सभी लूप पुनरावृत्तियों समान फ़ंक्शन-स्कूप किए गए iचर को साझा करते हैं , जिसमें 5लूप खत्म होने के बाद मूल्य होता है।


6
वह == के बजाय === अपनाने के बारे में एक ही जवाब देता है। उत्तरार्द्ध टूट गया है, लेकिन ईएस मानक समिति इसे बदलना नहीं चाहती थी, इसलिए उन्होंने === जोड़ा कि इसका क्या मतलब है, निश्चित रूप से नहीं। ==बिल्कुल नहीं टूटी है। इसे बस equality comparison using coersionचेक आउट github.com/getify/You-Dont-Know-JS/blob/master/… के
AmmarCSE

13
@AmmarCSE कि निहितार्थ पर एक अद्भुत 39 पृष्ठ डॉक्टर है। प्रोग्रामिंग करते समय सभी को कौन ध्यान में रख सकता है? डौग का अर्थ था "टूटा हुआ" जैसा कि स्टैकओवरफ्लो में संक्षेप में बताया गया है / a / 359509/1682419 , संक्षेप में , बिट प्राप्त करना आसान है जब मूल्य प्रकार हम प्रकल्पित से अधिक भिन्न होते हैं। क्या आप इन सब का अनुमान लगा सकते हैं? [ '1.0' == 1.0, [1.0] == 1.0, [1.0] == '1.0', ['1.0'] == 1.0, [null] == '', [null] == 'null', '00' == false, [] == [], [] == 0, [] == '', [] == false, [] == true, [010] - [4] == ' 4.0 ', !![0], !![1], [0] == true, [1] == true, 1 == [[1]], 0 == [[0]], '1' == [1] ]
जेरी

2
सही, उनमें से अधिकांश उदाहरणों में एक सरणी ऑपरेंड शामिल है। परिणाम को समझना आसान है जब आप स्ट्रींग में देखते हैं और ऑब्जेक्ट के लिए इसे कैसे लागू किया जाता है । हालाँकि, अगर वही है जो टूटने से है तो मैं पूरी तरह देखता हूँ कि वह कहाँ से आ रहा है। :-)
अम्मारसीएस

3
जब भी यह परस्पर नहीं है तो कास्ट का उपयोग क्यों न करें - बस पूछ रहा है? मेरा मतलब है, वास्तविक विकल्प यह के बीच नहीं है letऔर varबल्कि बीच let, varऔरconst
shabunc

4
varडिजाइन के रूप में काम करता है, लेकिन न जाने कितने लोग उम्मीद करते हैं। यह प्रयोज्य बग है, कार्यान्वयन बग नहीं।
जेरी १०

12

यदि आप सही कोड लिख रहे हैं, तो आप संभवतः सभी varबयानों को letबिना किसी अर्थ परिवर्तन के बयानों में बदल पाएंगे ।

letबेहतर है क्योंकि यह उस दायरे को कम करता है जिसमें एक पहचानकर्ता दिखाई देता है। यह हमें पहले उपयोग की जगह पर सुरक्षित रूप से चर घोषित करने की अनुमति देता है।

constके लिए बेहतर है let। जब तक आपको किसी संदर्भ को म्यूट करने की आवश्यकता नहीं है, तब तक एक constघोषणा का उपयोग करें । इसके साथ सभी लाभ हैं letसाथ ही साथ इकाईय चर की उपस्थिति को कम करने और कोड को आम तौर पर तर्क के लिए आसान बनाना है। यदि आपको यकीन नहीं है कि आपको एक संदर्भ को म्यूट करने की आवश्यकता होगी, तो इसे घोषित करें constजब तक आप अपने आप को स्पष्ट रूप से ऐसा करने की आवश्यकता नहीं पाते।


5

मैं जरूरी नहीं कि आप गलत हैं, लेकिन var का उपयोग करने के लिए चेतावनी दे रहे हैं। अनिवार्य रूप से, letडेवलपर्स को जावास्क्रिप्ट की मूर्खता के आसपास पहुंचने में मदद करनी चाहिए, विशेष रूप से नामकरण संघर्ष के साथ। varऐसा लगता है, एक बड़ा स्कोप है क्योंकि यह क्लोज फंक्शन स्कोप में जाना चाहता है। ऐसे समय होंगे जब आपको var की आवश्यकता होगी, जैसे कि जब आपको किसी फ़ंक्शन के अंदर एक ब्लॉक के दायरे में उपलब्ध होने के लिए एक अस्थायी चर की आवश्यकता होती है, अन्यथा, letvar को प्राथमिकता देने से डेवलपर्स को नामकरण संघर्षों में मदद मिलेगी। एक हल्के नोट पर, यह उस समय के बारे में है जिसे ES6 ने पेश किया था let


3
varब्लॉक में एक अस्थायी पूरे फ़ंक्शन के अंदर उपलब्ध है, न कि ब्लॉक-स्कॉप्ड। यह एक भ्रामक विशेषता है।
जेरी १०

1

मैं इस बात से सहमत हूं कि es6 में केवल "लेट" का उपयोग किया जाना चाहिए। एएफआईके, एक "लेट" को पुन: घोषित करने से एक त्रुटि उत्पन्न होती है (जो अच्छी है), जबकि "var" के साथ, आप बस मूल्य को ओवरराइड करते हैं (हालांकि es5 में "सख्त मोड" भी इसका ख्याल रखता है)।


-4

let"चर बराबर होने दो"। यह एक घोषणा है, दूसरे शब्दों में, एक आरंभीकरण और असाइनमेंट।

यह इसके विपरीत मौजूद है, constजिसका अर्थ है "स्थिर" - जो चर के विपरीत है।

कुछ अन्य भाषाएं वस्तु को घोषित करने के बजाय वास्तविक वस्तु के लिए एक उपसर्ग का उपयोग करती हैं (उदाहरण के defलिए "परिभाषित फ़ंक्शन" के लिए एक शॉर्टहैंड - पूरी तरह से "डीएफ़" होने के बिंदु को गायब करना।

Let यह शब्दार्थ विसंगति जावास्क्रिप्ट में जोड़ता है।

तार्किक रूप से, आप एक निरंतर बराबर कुछ दे सकते हैं, क्योंकि "लेट" कीवर्ड का काम मेमोरी को असाइन करना है।

समस्या इसलिए उत्पन्न होती है क्योंकि varकीवर्ड को constसमर्थन देने से पहले पेश किया गया था, इसलिए पीछे की संगतता तय करती है कि varएक चर का मतलब जरूरी नहीं है। (इसका उपयोग निरंतर मान प्रदान करने के लिए भी किया जा सकता है।)

इसलिए, letगलत स्थिति में परिचय । यह सुनिश्चित करने के लिए कि हमें याद है कि lexically, यह गलत है, उन्होंने भी letबनाम का शाब्दिक दायरा बदलने का फैसला किया var, इसलिए डिबगिंग करते समय हमारे दिमाग में असंगति सबसे महत्वपूर्ण है।

दूसरे शब्दों में, letमौजूद है क्योंकि लोग (भाषा के रखवाले) का अर्थ है कि जावास्क्रिप्ट बहुत सुसंगत था, यह सब मुहावरे और मूर्खतापूर्ण होने में महारत हासिल है, अधिक इच्छा।

साइड नोट, var"एरो" ब्लॉकों में काम नहीं करता है यदि आप उक्त ब्लॉकों को क्लोजर के रूप में व्यवहार करना चाहते हैं (क्योंकि varब्लॉक को क्लोजर के रूप में ट्रीट करने से पहले पेश किया गया था), लेकिन letकरता है।


6
-1: पांडित्य, अनहेल्दी और मुख्य रूप से राय-आधारित।
जोएल म्यूलर

फिजियारोन हमारे साथ यहां मजाक कर रहे हैं।
जेरी १०१

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

3
letसिर्फ डेवलपर्स अधिक जटिलता के इच्छुक नहीं है। यह वास्तव में सहज रूप से अधिक समझ में आता है, क्योंकि जब आप वार्स पर लूप-एंड-क्लोज करते हैं, तो क्लोजर var के अंतिम मान को बनाए रखता है, लेकिन जब आप वैसा ही ओवर करते हैं, तो लूप में प्रत्येक क्लोजर का अपना मान होता है, ऊपर @ जैरी १०१० से उदाहरण देखिए
TKoL
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.