2016-01-10 7 views
11

पर विचार करें निम्नलिखित कोड के टुकड़े'(ए में से एक) के लिए एक सरणी सही ढंग से क्यों कर सकता है?

var a = [1, 2, 3, 4]; 
for (a of a) { // The first 'a' is made by mistake 
    console.log(a); 
} 

पहले afor पाश में गलती से लिखा है। मुझे लगता है कि उपरोक्त कोड को त्रुटि चलनी चाहिए, क्योंकि जब a को पहले पुनरावृत्ति में 1 पर असाइन किया गया है, तो aपुनरावृत्त ऑब्जेक्ट नहीं है। तो अगली पुनरावृत्ति में एक त्रुटि फेंक दी जानी चाहिए।

वास्तव में, परिणाम निम्न प्रकार हैं:

1 
2 
3 
4 

ऐसा लगता है ऊपर कोड सही ढंग से सरणी पुनरावृति कर सकते हैं। for लूप के बाद, a का परिणाम 4 है। क्यों?

> a 
4 

आगे की जांच पड़ताल के लिए, मैं ECMA-6 doc से कुछ जानकारी प्राप्त करने की कोशिश की, लेकिन मैं निम्नलिखित बयान से उलझन में हूँ।

(AssignmentExpression का वर ForBinding) वक्तव्य

के लिए (AssignmentExpression की ForDeclaration) वक्तव्य

के लिए ForBinding और ForDeclaration को समझने के लिए, निम्न कोड का परीक्षण।

var a = [1, 2, 3, 4]; 
for (var a of a) { 
    console.log(a); 
} 
console.log(a); 

दुर्भाग्यवश, परिणाम पिछले कोड के समान है। for (var a in a) और for (a in a) के बीच क्या अंतर है?

उत्तर

9

for इस पर और "AssignmentExpression" का मान दोहराता मूल्यांकन करता है। मूल्य पुनरावृत्ति की शुरुआत में केवल एक बार प्राप्त किया जाता है, इसलिए एक ही चर का पुन: उपयोग करना पूरी तरह मान्य है (यह भी काफी उलझन में है)।

var की उपस्थिति: for (a of ...) और for (var a of ...) कोड में किसी भी फर्क नहीं करता है के रूप में आप पहले से ही a परिभाषित किया गया है - तो यह सिर्फ एक ही चर फिर से घोषित करेंगे।


वहाँ मामलों में जहां व्यवहार अलग है कर रहे हैं पूरी तरह से सटीक होना - जब a वर्तमान समारोह var संस्करण है कि मूल्य (शैडो होगा जावास्क्रिप्ट में के रूप में के लिए बाहरी दायरे में घोषित किया जाता है सभी var बयान समारोह दायरे के शीर्ष करने के फहराया जाता है):

var a = [1,2,3]; 
function tryForVar() { 
    // Note that declaration of `a` is hoisted here as var a = undefined; 
    // for (var a ... does not work as expected as local 'a' is undefined 
    for (var a of a) { 
    console.log(a); // log 'undefined' once 
    } 
    console.log(a); // undefined 
} 
tryForVar(); 
console.log(a); // [1,2,3] 

function tryFor() { 
    // Note that declaration of `a` from outer scope 
    // for (a ... works fine as it uses outer 'a' 
    for (a of a) { 
    console.log(a); // logs all 1,2,3 in sequence 
    } 
    console.log(a); // 3 
} 
tryFor(); 
console.log(a); // 3 
+0

ऐसा एकमात्र ऐसा उत्तर लगता है जो वास्तव में प्रश्न को संबोधित करता है और यह एकमात्र सही उत्तर भी प्रतीत होता है। निश्चित नहीं है कि किसी और ने इसे एक डाउनवोट क्यों दिया। मुझसे +1 – jfriend00

+6

मैंने वोट नहीं दिया, लेकिन 'var' के साथ घोषित चर पुन: घोषित नहीं किए गए हैं। घोषणापत्र उनके दायरे में फंस गए हैं, और बाद में कोड में 'var की मुलाकात _ignored_ हैं। – Teemu

+1

@Teemu हां, मेरा बयान वास्तव में oversimplification है और इसके बजाय "अगर आप 'var' संस्करण का उपयोग करें, तो पहले और बाद में लूप के अर्थ 'ए' का अर्थ समान होगा, लेकिन यह होस्टिंग के कारण बाहरी दायरे से चर को छाया कर सकता है (और इसलिए आप जो भी कर रहे हैं उसे पूरी तरह बदल दें) "। –

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