2012-01-05 8 views
10

मैं जावास्क्रिप्ट या क्रोम कंसोल के व्यवहार से गहराई से उलझन में हूं। क्या कोई मुझे समझने में मदद कर सकता है?जावास्क्रिप्ट कंसोल को निर्दिष्ट किए जाने से पहले वैरिएबल का असाइन मान मुद्रित करता है?

असल में मैं निम्नलिखित जावास्क्रिप्ट कोड, किसी भी समारोह या अन्य दायरे के अंदर नेस्टेड नहीं किया है:

var initial_array = []; 

function initialiseArray() { 
    initial_array = [2, 9, 8, 6, 0, 2, 1]; 
} 

function copyToNewArray() { 
    var copied_array = []; 

    console.log("COPIED 1", copied_array); 

    for (var i = 0; i < initial_array.length; i++) { 
     var copy = initial_array[i]; 
     copied_array.push(copy); 
    } 

    console.log("COPIED 2", copied_array); 
} 

initialiseArray(); 
copyToNewArray(); 

मैं COPIED 1 उम्मीद करेंगे [] मुद्रित करने के लिए - चर के रूप में अभी तक असाइन नहीं की गई है - लेकिन इसके बजाय यह प्रिंट [2, 9, 8, 6, 0, 2, 1] - यानी इसके बाद मूल्य असाइन किया गया है।

क्यों?

संयोग से, यदि आप initial_array = copied_array के साथ लाइन 8-11 को प्रतिस्थापित करते हैं, तो RESULTS 1 वास्तव में [] के रूप में प्रिंट करता है। क्या .push का उपयोग करने के साथ कुछ करना है?

+0

दिलचस्प। क्या यह एक ही मुद्दे को संबोधित करता है? [लिंक] (http://zef.me/2843/javascript-the-scope-pitfall) – j08691

+4

समान प्रश्न: http://stackoverflow.com/questions/4057440/is-chromes-javascript-console-lazy-about- मूल्यांकन-एरे – diEcho

उत्तर

8

क्रोम स्क्रिप्ट डीबगर में अपनी समस्या डिबगिंग प्रयास करें इससे पहले कि सरणी कॉपी कर सकते हैं।लाइन पर ब्रेकपॉइंट रखें:

for (var i = 0; i < initial_array.length; i++) { 

और आप जिस व्यवहार को चाहते हैं उसे देखेंगे।

आपकी समस्या यह है कि आप गलत धारणा कर रहे हैं कि क्रोम डीबगर 'प्रिंट' को तत्काल मान देता है जब वास्तव में यह console.log असीमित रूप से करता है। चूंकि सरणी बैकएंड में संदर्भ द्वारा चारों ओर पारित होती है जब यह वास्तव में मूल्य मुद्रित करने के लिए जाती है, यह अब आप देख रहे हैं।

+0

क्रोम स्क्रिप्ट डीबगर के लिए अच्छी सिफारिश, मैं बिना किसी सफलता के वेबस्टॉर्म डीबगर के साथ प्रयास कर रहा था। – Osy

+0

अच्छा जवाब ... LAME लॉगर :( – Nicole

0
var initial_array = []; 
function initialiseArray() { 
    initial_array = [2, 9, 8, 6, 0, 2, 1]; 
} 
function copyToNewArray() { 
    var copied_array = []; 
    console.log("COPIED 1", copied_array); 
    alert(copied_array.length); 
    for (var i = 0; i < initial_array.length; i++) { 
     var copy = initial_array[i]; 
     copied_array.push(copy); 
    } 
    console.log("COPIED 2", copied_array); 
} 
initialiseArray(); 
copyToNewArray(); 

लाइन alert(copied_array.length); जोड़ना सही परिणाम दिखाएगा।

क्या होता है कि लॉग जावास्क्रिप्ट निष्पादन के साथ सिंक्रनाइज़ नहीं किया जाता है। जब लॉग प्रिंट करता है तो मान पहले ही बदल दिए गए थे।

1

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

var initial_array = []; 

function initialiseArray() { 
    initial_array = [2, 9, 8, 6, 0, 2, 1]; 
} 

function copyToNewArray() { 
    var copied_array = []; 

    console.log("COPIED 1", copied_array.toString()); 

    for (var i = 0; i < initial_array.length; i++) { 
     var copy = initial_array[i]; 
     copied_array.push(copy); 
    } 

    console.log("COPIED 2", copied_array.toString()); 
} 

initialiseArray(); 
copyToNewArray(); 

आप बहुत आसानी से इस परीक्षण कर सकते हैं:

var x = []; 
console.log(x), x.push(5), x; // outputs [5] and [5] 
+0

फिर भी, आपको लगता है कि यह उचित बिंदु पर सरणी संदर्भ प्रस्तुत/कंक/संकलित करेगा, अन्यथा 'console.log'ging arrays बहुत अधिक काम नहीं करेगा। फ़ायरफ़ॉक्स भी इस पर झुकाएगा, या यह अधिक बुद्धिमान है? –

+0

@ लाइटनेसरेसेसिन ऑर्बिट: अधिक बुद्धिमान नहीं, बल्कि सभी चीजों को तारों में परिवर्तित करता है, इसलिए हाँ इसे काम करना चाहिए। (फायरबग, दूसरी तरफ ... मुझे यकीन नहीं है।) – Ryan

+0

मैं प्रस्ताव करता हूं कि _is_ "अधिक बुद्धिमान", क्योंकि इस मामले में इतनी देर से संदर्भित संदर्भ को स्पष्ट रूप से पीओएलएस का उल्लंघन करता है। (एफडब्ल्यूआईडब्ल्यू, मेरा मतलब फायरबग कहना था) –

1

सांत्वना वास्तव में अतुल्यकालिक है। चूंकि आप किसी ऑब्जेक्ट का संदर्भ लॉग कर रहे हैं, जब तक ऑब्जेक्ट लॉग होता है, यह पहले ही बदल चुका है।

आप यह सुनिश्चित करने के लिए सरणी को क्लोन कर सकते हैं कि यह लॉग होने से पहले इसे बदला नहीं जा सकता है।

3

चूंकि सरणी संदर्भ द्वारा पारित की जाती हैं, इसलिए आप जो भी परिवर्तन करते हैं, वह कंसोल में आउटपुट को बदल देगा। यह आंशिक रूप से क्रोम के कंसोल का व्यवहार है, आंशिक रूप से जावास्क्रिप्ट।

यदि आप कॉल के समय console.log पर परिणाम प्रिंट करना चाहते हैं, तो आप इसे JSON.stringify का उपयोग कर स्ट्रिंग के रूप में आउटपुट कर सकते हैं।

console.log("COPIED 1", JSON.stringify(copied_array)); 

महत्वपूर्ण संपादित

ऐसा लगता है मैं ज्यादातर गलत था। diEcho प्रश्न की टिप्पणियों में बताया गया है, similar question में better answer है। ऐसा लगता है कि यह पूरी तरह क्रोम व्यवहार है।

+0

मुझे यह व्यवहार फ़ायरफ़ॉक्स वेब डेवलपर कंसोल (स्टॉक ब्राउज़र एक, फ़ायरबग नहीं) में भी मिलता है। तो शायद यह केवल क्रोम व्यवहार ही नहीं है। –

0

ऐसा इसलिए है क्योंकि copied_array एक संदर्भ है, और console.log को असीमित रूप से निष्पादित किया जाता है, इसलिए सरणी की सामग्री को पहले लॉग प्रिंट करने से पहले संशोधित किया जाता है।

आप मुद्रण

console.log([].concat(copied_array)); 
2

console.log("COPIED 1", JSON.stringify(copied_array));

डिबगिंग


यह एक बग आपने उल्लेख किया है है के लिए ठीक होना चाहिए, नीचे

https://bugs.webkit.org/show_bug.cgi?id=35801

देखना भी इसी तरह के सवाल

पढ़ 10

Bizarre console.log behaviour in Chrome Developer Tools

Why does javascript object show different values in console in Chrome, Firefox, Safari?

0

आप इस तरह के एक सरणी में वस्तुओं के विस्तार के रूप में कंसोल की कार्यक्षमता को बनाए रखना चाहते हैं, तो मैं .slice, जब प्रवेश करने जो सरणी जो परिवर्तन नहीं करता है की एक प्रतिलिपि बनाता उपयोग करने का सुझाव :

console.log("COPIED 1", copied_array.slice()); 
+0

अच्छा लेकिन JSON.stringify (copied_array) विधि बेहतर लगता है, मुझे लगता है। –

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