2015-08-05 8 views
9

यदि let कीवर्ड ब्लॉक स्कोप का उचित कार्यान्वयन प्रस्तुत करता है, तो var में अब कोई उपयोग केस नहीं है? मैं इसे एक वाक्य रचनात्मक, "अच्छी तरह से आप" दृष्टिकोण के बजाय एक सॉफ्टवेयर डिजाइन दृष्टिकोण से देख रहा हूँ।ES6 में var के लिए उपयोग केस क्या है?

+0

संबंधित: http://stackoverflow.com/questions/762011/javascript-let-keyword- बनाम-var-keyword – Marvin

+1

मैं अंतर को समझता हूं, मैं अभी प्रोग्रामिंग दिमाग चुनने की कोशिश कर रहा हूं क्योंकि क्यों 'var' हमेशा सामान्य उपयोग को छोड़ नहीं देगा। –

+0

संभावित डुप्लिकेट [एक चर घोषित करने के लिए "let" और "var" का उपयोग करने के बीच क्या अंतर है?] (Https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and- var-to-declare-a-variable) –

उत्तर

8

यदि let कीवर्ड ब्लॉक स्कोप का उचित कार्यान्वयन प्रस्तुत करता है, तो var में अब कोई उपयोग केस नहीं है?

एक उपयोग का मामला हो सकता है: let वैश्विक दायरे में घोषणा वैश्विक वस्तु पर एक संपत्ति नहीं बनाती है। उदाहरण:

"use strict"; // for chrome 
 
var foo = 42; 
 
let bar = 21; 
 
console.log('window.foo (var)', window.foo); // 42 
 
console.log('window.bar (let)', window.bar); // undefined

से 8.1.1.4 Global Environment Records

एक वैश्विक पर्यावरण रिकार्ड की वस्तु Environment Record घटक सभी में निर्मित वैश्विक (clause 18) और सभी बाइंडिंग एक द्वारा शुरू की के लिए बाइंडिंग शामिल फ़ंक्शन डिस्क्लेरेशन, जनरेटर डिस्क्लेरेशन, या परिवर्तनीय स्टेटमेंट वैश्विक कोड में निहित है। वैश्विक कोड में अन्य सभी ईसीएमएस्क्रिप्ट घोषणाओं के लिए बाइंडिंग वैश्विक पर्यावरण रिकॉर्ड के घोषणात्मक पर्यावरण रिकॉर्ड घटक में निहित हैं।

बहरहाल, यह भी आसानी से उपयोग कर एक स्पष्ट वैश्विक चर बनाने के द्वारा हल किया जा सकता वैश्विक वस्तु सीधे करने के लिए बताए द्वारा:

window.foo = 42; 

यह भी होगा btw वैश्विक कक्षाएं बनाने के लिए एक ही रास्ता , क्योंकि class घोषणा का एक ही व्यवहार है।

(नोट: मैं वैश्विक चर का उपयोग की वकालत नहीं कर रहा हूँ)


वाक्य रचना निर्माणों जहां केवल var का उपयोग कर सकते हैं, लेकिन है कि और अधिक का एक परिणाम कैसे कल्पना का विकास हुआ और नहीं करता है 'है टी वास्तव में किसी भी व्यावहारिक उद्देश्य की सेवा नहीं करते हैं। उदाहरण के लिए:

if (true) 
    var foo = 42; // valid but kind of useless or bad design 

// vs 

if (true) 
    let foo = 42; // invalid 

ब्लॉक गुंजाइश ही उपयोगी सुविधा है, हालांकि नहीं है। temporal dead zone बग को अधिक आसानी से ढूंढने के लिए एक और आसान सुविधा है।की तुलना करें:

var foo = 42; 
function bar() { 
    console.log(foo); // undefined 
    var foo = 21; 
} 
bar(); 

// vs 

var foo = 42; // or `let`, doesn't matter 
function bar() { 
    console.log(foo); // ReferenceError, temporal dead zone 
    let foo = 21; 
} 
bar(); 

आप जब एक let चर कि अभी तक प्रारंभ नहीं किया गया था एक्सेस करते समय संदर्भ त्रुटि मिलती है।

+1

जो आप कह रहे हैं, उससे ऐसा लगता है कि 'लेट' व्यवसाय तर्क के लिए एक कठोर वातावरण पेश करता है।यह मेरी राय है कि इसे प्रबुद्ध मंडलियों में समय के साथ 'var' के उपयोग को चरणबद्ध करना होगा। –

3

let वैश्विक क्षेत्र अभी तक में उपयोग नहीं किया जा सकता है। var कर सकते हैं।

यह तुम क्या क्रोम से मिलता है जब आप सख्त मोड के एक वैश्विक let बाहर की कोशिश है:

ब्लॉक-दायरे घोषणाओं (चलो, स्थिरांक, समारोह, वर्ग) अभी तक सख्त मोड

बाहर समर्थित नहीं
+0

क्या यह spec स्वयं या वर्तमान कार्यान्वयन से परिणाम है? –

+1

@ कामुलेफ्रैंको: स्पष्ट रूप से एक कार्यान्वयन सीमा – Bergi

0

व्यावहारिक रूप से मेरे लिए कुछ उपयोग-मामले पाए गए हैं।

कभी कभी तुम इतनी तरह कोशिश पकड़ में चर घोषित करने के लिए चाहते हो सकता है:

try { 
    //inits/checks code etc 
    let id = getId(obj); 

    var result = getResult(id); 
} catch (e) { 
    handleException(e); 
} 

//use `result` 

let साथ result घोषणा try है, जो थोड़ा जल्दी और संदर्भ से बाहर के लेखक और एक पाठक के लिए है से पहले किया जाएगा कोड का कि हालांकि अव्यावहारिक हो सकता है,

if (opts.re) { 
    var re = new RegExp(opts.re); 
    var result = match(re); 
    if (!result) return false; 
} 

//use result here safely 

let के साथ इस कोड को थोड़ा "अच्छा शैली" शिकायत करने के लिए मजबूर होगा:

ही सशर्त घोषणाओं के लिए है।

इसके अलावा, मैं इस मामले में जहां आप पाश ब्लॉक से संबंधित चर का उपयोग करना चाहते हैं कल्पना कर सकते हैं:

for (var x = 0; x < data.width; x++) { 
    if (data[x] == null) break; 
    //some drawing/other code 
} 

//here we have the `x` pointing to the end of data 

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

0

एक मूल्यवान उपयोग केस: पुनरावृत्ति प्रदर्शन।

spec के पास प्रत्येक पुनरावृत्ति (§ 13.7.4.9) के लिए एक नया वातावरण बनाने के लिए लूप हेड में let है। यह लूपों में बंद करने के लिए आसान बनाने के लिए है। इसके विपरीत var पूरे लूप के लिए एक वातावरण बनाता है।

मैं एक for पाश बनाने letके रूप में दिखाने 3-4 बार धीमी दोनों नोड और ब्राउज़र (performance test here) में:

const iterations=1000000000; // 1 billion iterations 
for(var i=0;i<iterations;i++); // 1.558 seconds 
for(let i=0;i<iterations;i++); // 4.986 seconds (*** 3-4 times slower than the others) 
var i;(i=0;i<iterations;i++); // 1.381 seconds 
let i;(i=0;i<iterations;i++); // 1.36 seconds 
var i=0;(;i<iterations;i++); // 1.37 seconds 
let i=0;(;i<iterations;i++); // 1.389 seconds 

var का उपयोग करते हुए आसपास के समारोह पर्यावरण को प्रदूषित करता है। लूप के बाहर let का उपयोग प्रदर्शन हिट को रोकता है लेकिन अभी भी आसपास के ब्लॉक वातावरण को प्रदूषित करता है।

यदि आप चाहते हैं प्रदर्शन के बिना एक पाश-स्थानीय यात्रा चर मारा तो आप इस दर्दनाक मुहावरा उपयोग कर सकते हैं:

{let i=0;for(;i<100;i++){ 
    console.log(i); // iteration code here 
}} 
i; // ReferenceError: i is not defined 
+0

spec में 'इन इन' और 'लूप्स' के लिए एक ही चीज़ हो रही है। नोड में मैं 'var'' पर 'var' 50% तेज और 'के लिए' पर एक ही गति दिखाता हूं। ब्राउज़र बेंचमार्क में वे हमेशा एक ही गति के प्रतीत होते हैं। यह मेरे लिए अस्पष्ट है कि वे सामान्य 'लूप' से अलग क्यों हैं और विभिन्न वातावरण में भिन्न होते हैं। [के लिए सबसे अधिक] (http://jsbench.github.io/#af642344be06436a331f626e73c0aaa9)/[perftest के लिए] (http://jsbench.github.io/#628087cbe1c795ae44a74c9d3565b50b) – Lycan

+0

इन चीजों से पहले यह सिर्फ समय की बात है अनुकूलित। यदि प्रत्येक पुनरावृत्ति पर बनाए गए दायरे की कोई आवश्यकता नहीं है, तो एक अनुकूलन संकलक इसे खत्म करने में सक्षम होना चाहिए। यह प्रदर्शन प्रदर्शन निर्धारित करने के लिए विश्वसनीय नहीं है, क्योंकि कार्यान्वयन विवरण इससे भिन्न हो सकते हैं और अनुकूलन मूल रूप से चीजों को बदल सकते हैं। –

संबंधित मुद्दे