2015-03-25 5 views
14

बस जिज्ञासा से बाहर के बीच अंतर ..उलझाव से वैश्विक "आइटम" चर - इंटरनेट एक्सप्लोरर और फ़ायर्फ़ॉक्स

मैं इस राशि जे एस कोड:

var someExternalArray = [{id: 1, name: 'a'}, {id: 2, name: 'b'}, {id: 3, name: 'c'}]; 
var newArray = [] 

//var item; 
for (var i = 0; i < someExternalArray.length; i++){ 
    item = new Object(); 
    item.id = someExternalArray[i].id; 
    item.name = someExternalArray[i].name; 
    newArray.push(item); 
} 

alert('0:' + newArray[0].name + ',1:' + newArray[1].name + ',2:' + newArray[2].name); 

सूचना टिप्पणी की var item जो परोक्ष घोषित साथ पाश छोड़ देता है item चर।

  • अगर मैं फ़ायर्फ़ॉक्स पर इस कोड को चलाने के लिए, चेतावनी का परिणाम है: 0:a,1:b,2:c

  • अगर मैं इंटरनेट एक्सप्लोरर में एक ही कोड चलाने के लिए, परिणाम है: 0:c,1:c,2:c

यहां jsfiddle है: https://jsfiddle.net/fvu9gb26/

बेशक, जब मैंको अनदेखा करता हूं 10 यह हर ब्राउज़र में एक ही तरह से काम करता है।

क्या कोई जानता है कि यह अंतर क्यों होता है? धन्यवाद।

उत्तर

7

असल में, ऐसा इसलिए है क्योंकि इंटरनेट एक्सप्लोरर की window ऑब्जेक्ट item() विधि का खुलासा करता है कि आपकी स्क्रिप्ट ओवरराइट नहीं कर सकती है।

लाइन में:

item = new Object(); 

item स्थानीय दायरे में घोषित नहीं किया गया है, तो यह वैश्विक वस्तु (window.item) के एक संपत्ति के रूप में व्याख्या की है। फ़ायरफ़ॉक्स पर, windowitem नामक सदस्य का खुलासा नहीं करता है, इसलिए एक नया सदस्य पेश किया गया है और new Object() का परिणाम इसे सौंपा गया है।

दूसरी तरफ, इंटरनेट एक्सप्लोरर window.item() नामक मूल विधि का खुलासा करता है। वह सदस्य लिखने योग्य नहीं है, इसलिए असाइनमेंट नहीं हो सकता है - इसे चुपचाप अनदेखा किया जाता है। दूसरे शब्दों में, item = new Object() पर कोई प्रभाव नहीं पड़ता है (ठीक है, यह ऑब्जेक्ट बनाता है लेकिन बाद में इसे असाइन नहीं कर सकता)।

id और name के बाद के असाइनमेंट item() विधि के नए सदस्यों को बनाते हैं। ये हमेशा एक ही विधि के समान सदस्य होते हैं, इसलिए उनके मूल्य प्रत्येक लूप पुनरावृत्ति पर ओवरराइट किए जाते हैं। इसके अतिरिक्त, एक ही ऑब्जेक्ट (item() विधि) प्रत्येक पुनरावृत्ति पर सरणी को धक्का दिया जाता है।

इसलिए, सरणी ऊपर तीन बार एक ही वस्तु युक्त क्रमशः 3 और 'c' समाप्त होता है, और उसके id और name सदस्यों के मूल्यों (पिछले चरण में) उन्हें सौंपे गए पिछले मान होते हैं,।

+0

धन्यवाद। यह वास्तव में एक संयोग था कि हम 'var item' घोषित करना भूल गए क्योंकि हम हमेशा हमारी परियोजना में चर घोषित करते हैं और कभी भी निहित घोषणाओं पर भरोसा नहीं करते हैं। और दूसरा, कि इस चर के पास 'विंडो ऑब्जेक्ट' पर कुछ मूल विधि के समान नाम है जो केवल आईई में मौजूद है .. वाह :) –

5

यह मुश्किल है। कुछ अस्पष्ट कारणों से, इंटरनेट एक्सप्लोरर के पास वैश्विक संदर्भ window में item नामक मूल विधि है (यदि कोई जानता है कि क्यों, आप साझा करने के लिए स्वागत करते हैं: मुझे इसे दस्तावेज़ में नहीं मिल रहा है)। इसलिए, जब आप एक चर घोषित किए बिना पहचानकर्ता item का उपयोग करते हैं, तो यह इस विधि को संदर्भित करता है।

लूप (item = new Object();) में पहला निर्देश कुछ भी नहीं है क्योंकि window.item एक पठनीय संपत्ति है। तो, इस निर्देश के बाद, window.item अभी भी मूल कार्य है।

अगले निर्देश (उन जो id और name सेट) काम करता है, क्योंकि संपत्ति window.item केवल पढ़ने के लिए है, जबकि, Function वस्तु यह की ओर इशारा करते है संशोधित किया जा सकता।

छोरों के बाद, आप एक ही Function वस्तु तीन बार, और केवल पिछले यात्रा मायने रखता है क्योंकि आप id और name गुण हर ओवरराइड गयी।

+1

एलएमओओ !! मैं यहां पर ठोकर खाई क्योंकि मैं आइटम संदर्भ के साथ-साथ लूप के लिए भी उपयोग कर रहा था। मैं जेएसओएन से अपनी सूची से वस्तुओं के माध्यम से लूपिंग कर रहा था और वैरिएबल आइटम को सौंपा ... अजीब सामान माइक्रोसॉफ्ट! Haha। मेरे लिए सरल फिक्स सिर्फ आइटम से पहले var जोड़ने के लिए था। –

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