Array.push()使所有元素在推送对象时相同
我是新来的节点和JavaScript,并一直在我的脑袋下面。 我已经创build了一个对象,如下所示:
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的最后一个值匹配,就像这样(两个不同的用户从DB中拉出来):
[ { userID: 4fc53a71163006ed0f000002, email: 'test@test.com', name: 'undefined undefined', stage: 'new', poster: false, canEmail: true }, { userID: 4fc53a71163006ed0f000002, email: 'test@test.com', name: 'undefined undefined', stage: 'new', poster: false, canEmail: true } ]
推出一个单一的元素而不是整个对象似乎是好的。 我添加了“foo”数组作为testing,它工作正常:
Heres foo now: [ 'email1@foo.com', 'test@test.com' ]
这里发生了什么?!?!??!
问题不在于Array.prototype
的push
方法,而在于绑定。 您正在修改async.foreach
块中的每个迭代中相同的s
对象, async.foreach
块与先前定义的Subscriber
实际上是相同的对象。
首先你应该把s
variables的声明移到foreach块。
而且,如果你想创build一个默认值的对象,它应该是一个function
,它返回一个新的对象:
function Subscriber() { return { 'userID': '', 'email': '', 'name': '', 'stage': '', 'poster': false, 'canEmail': false, 'stage': '' }; };
然后你可以像这样实例化一个Subscriber
对象:
var s = Subscriber();
有关更多说明,请参阅MDN上的 此答案或“ 闭包” 。
您必须每次都复制订阅者。 否则,每次修改相同的对象。 只需使用s = copy(Subscriber)