2012-06-07 8 views
9

मैं नोड के लिए नया हूँ और जावास्क्रिप्ट और निम्नलिखित पर मेरे सिर की पिटाई कर दिया है धक्का बनाता है।Array.push() सभी तत्वों को एक ही जब एक वस्तु

var Subscriber = { 
'userID': String, 
'email': String, 
'name': String, 
'stage': String, 
'poster': Boolean, 
'canEmail': Boolean, 
'stage': String, } 

मैं परिणामों के माध्यम से एक समारोह है, जहां मैं MongoDB क्वेरी, और पाश है, ग्राहकों की एक सरणी है, जो मैं के रूप में घोषित किया है लोड करने का प्रयास:

var s = Subscriber; 
var subscribers = []; 
मैं एक वस्तु के रूप में निम्नानुसार बना लिया है

पाश इस तरह दिखता है:

//load array of users that are subscribed to the group 
     async.forEach(g.subscribers, function(item, callback) {  
      //load user document for this user 
      User.findOne({ _id: item}, function(err, u) { 
       if(!err && u) {     
        //var s = new Subscriber(); 
        console.log('Sub load, found user %s, building array item', u.email); 
        console.log('Subs @ loop start'); 
        console.log(util.inspect(subscribers)); 

        console.log('Heres foo: ' + util.inspect(foo)); 


        s.userID = u._id; 
        s.email = u.email; 
        s.name = u.firstName + ' ' + u.lastName; 
        s.stage = u.stage; 
        s.poster = false; //we're just loading subscribers at this point' 
        if(s.stage != 'new') s.canEmail = true; 

        //push new subscriber onto the array 
        console.log('Pushing ' + util.inspect(s)); 
        subscribers.push(s); 

        console.log('At end ' + util.inspect(subscribers)); 

        foo.push(s.email); 
        console.log('Heres foo now: ' + util.inspect(foo)); 

        callback(null, item); 
       } 

के बाद प्रत्येक कॉल subscribers.push को (s), सरणी तत्वों की सही संख्या है, लेकिन सभी तत्वों, (के साथ के लिए पिछले मान से मेल इस तरहदो अलग-अलग उपयोगकर्ताओं डीबी से खींचा जा रहा है):

[ { userID: 4fc53a71163006ed0f000002, 
email: '[email protected]', 
name: 'undefined undefined', 
stage: 'new', 
poster: false, 
canEmail: true }, 
    { userID: 4fc53a71163006ed0f000002, 
email: '[email protected]', 
name: 'undefined undefined', 
stage: 'new', 
poster: false, 
canEmail: true } ] 

पूरी वस्तु के बजाय एस के एक भी तत्व धकेल ठीक हो रहा है। मैंने एक परीक्षण के रूप में "foo" सरणी जोड़ा, और यह ठीक काम करता है:

Heres foo now: [ '[email protected]', '[email protected]' ] 

यहां क्या हो रहा है?!? !??

+0

क्या 'g.subscribers' कैसा दिखता है प्राप्त करें? – alessioalex

+2

वस्तुओं और सरणियों (जो वस्तुओं रहे हैं) जावास्क्रिप्ट में संदर्भ द्वारा पारित कर रहे हैं। यदि 's' एक वस्तु है, और आप कर रहे हैं यह केवल गुणों को बदलने और उसके बाद एक पाश में सरणी पर एक ही वस्तु धक्का द्वारा फिर से उपयोग कर रहा है, तो सरणी में वस्तुओं एक ही वस्तु के सभी संदर्भ हैं। – Steve

+0

धन्यवाद! यह बहुत उपयोगी था। मैं सोच रहा था कि यह संदर्भों के साथ कुछ हो सकता है लेकिन मेरे सिर को इसके चारों ओर लपेट नहीं सका। मुझे लगता है कि यह क्या होता है जब आप कर रहे हैं पिछले देव काम दो दशक पहले पास्कल और सी की तरह किनारे भाषाओं को काटने में किया गया था है! – pat

उत्तर

13

समस्या Array.prototype की push विधि के साथ नहीं है बल्कि आपकी बाध्यताओं के साथ है। आप अपने async.foreach ब्लॉक जो वास्तव में पहले से परिभाषित Subscriber रूप में एक ही वस्तु है में हर चरण में एक ही s वस्तु संशोधित कर रहे हैं।

पहले तुम foreach ब्लॉक करने के लिए s चर की घोषणा बढ़ना चाहिए।

और यह भी आप मूलभूत मूल्यों के साथ एक वस्तु बनाना चाहते हैं, यह एक function है, जो एक नया ऑब्जेक्ट होना चाहिए:

function Subscriber() { 
    return { 
    'userID': '', 
    'email': '', 
    'name':  '', 
    'stage': '', 
    'poster': false, 
    'canEmail': false, 
    'stage': '' 
    }; 
}; 

और फिर आप एक Subscriber वस्तु इस तरह का दृष्टांत कर सकते हैं:

var s = Subscriber(); 

this answer या अधिक विवरण के लिए Closures on MDN देखें।

-1

आप सब्सक्राइबर हर बार की प्रतिलिपि करने के लिए है। अन्यथा आप हर बार एक ही वस्तु को संशोधित करते हैं। बस सरणी में धकेलने से पहले वस्तु क्लोनिंग s = copy(Subscriber)

+0

'copy' Node.js वातावरण में परिभाषित नहीं है। –

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