javascript Array.push() 使所有元素在推送对象时都相同
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10932584/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Array.push() makes all elements the same when pushing an object
提问by pat
I'm new to node and javascript and have been banging my head on the following. I've created an object as follows:
我是 node 和 javascript 的新手,并且一直在思考以下问题。我创建了一个对象,如下所示:
var Subscriber = {
'userID': String,
'email': String,
'name': String,
'stage': String,
'poster': Boolean,
'canEmail': Boolean,
'stage': String, }
I have a function where I query mongodb, and loop through the results, attempting to load an array of subscribers, which I've declared as:
我有一个查询 mongodb 的函数,并循环遍历结果,尝试加载订阅者数组,我已将其声明为:
var s = Subscriber;
var subscribers = [];
The loop looks like this:
循环如下所示:
//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);
}
After each call to subscribers.push(s), the array has the correct number of elements, but all elements match the last values for s, like this (with two different users being pulled from the DB):
每次调用subscribers.push(s) 后,数组都有正确数量的元素,但所有元素都匹配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 } ]
Pushing a single element of s rather than the whole object seems to be fine. I added the "foo" array as a test, and it works fine:
推送 s 的单个元素而不是整个对象似乎没问题。我添加了“foo”数组作为测试,它工作正常:
Heres foo now: [ '[email protected]', '[email protected]' ]
What is going on here?!?!??!
这里发生了什么?!?!??!
回答by KARASZI István
The problem is not with the push
method of the Array.prototype
but with your bindings.
You are modifying the same s
object in every iteration in your async.foreach
block which is actually the same Object as the previously defined Subscriber
.
问题不在于push
方法,而在于Array.prototype
你的绑定。您正在块s
中的每次迭代中修改相同的对象,async.foreach
它实际上与先前定义的对象相同Subscriber
。
First you should move the declaration of the s
variable to the foreach block.
首先,您应该将s
变量的声明移动到 foreach 块。
And also if you want to create an object with default values, it should be a function
, which returns a new object:
而且,如果您想创建一个具有默认值的对象,它应该是 a function
,它返回一个新对象:
function Subscriber() {
return {
'userID': '',
'email': '',
'name': '',
'stage': '',
'poster': false,
'canEmail': false,
'stage': ''
};
};
And then you can instantiate a Subscriber
object like this:
然后你可以Subscriber
像这样实例化一个对象:
var s = Subscriber();
See this answeror Closures on MDNfor more explanation.
回答by Ben
Cloning the object before pushing into the array, also solves the problem.
在推入数组之前克隆对象,也解决了问题。
temp = clone(s);
subscribers.push(temp);