_.find return 是对象的引用吗?如何正确设置结果的属性?

Does _.find return a reference to the object? How to properly set a property of the result?

我使用 lodash find 从数组中查询对象,然后我设置了那个对象的 属性 但是当我在设置这个 属性 后打印出数组时,它没有改变.

如果有人在 JavaScript 中对使用 lodash 处理对象更有经验,我将不胜感激。也可以随意评论我提出问题的方式或编辑内容,使其更容易通过搜索引擎被其他人搜索到。

孤立代码:

console.log('socket.io', token);
console.log(realtime);
let session = yield _.find(realtime, function(data) {
    return data.token === token;
});
console.log('session object to be set');
console.log(session);
if (!session.socket) {
    console.log('setting session for '+session.token+' socket '+socket.id);
    session.socket = socket.id;
    console.log('local reference after set');
    console.log(session);
    console.log('realtime after set');
    console.log(realtime);
}

结果,这是console.log的输出:

socket.io 268fc477-d4ee-4ed4-88cd-648539397df2
[ { token: '268fc477-d4ee-4ed4-88cd-648539397df2' } ]
session object to be set
{ token: '268fc477-d4ee-4ed4-88cd-648539397df2' }
setting session for 268fc477-d4ee-4ed4-88cd-648539397df2 socket /#iEqqcIsBbATDs1a-AAAB
local reference after set
{ token: '268fc477-d4ee-4ed4-88cd-648539397df2',
socket: '/#iEqqcIsBbATDs1a-AAAB' }
realtime after set
[ { token: '268fc477-d4ee-4ed4-88cd-648539397df2' } ]

预期结果,看最后打印,我想在对象起源的数据结构中修改这个对象:

socket.io 268fc477-d4ee-4ed4-88cd-648539397df2
[ { token: '268fc477-d4ee-4ed4-88cd-648539397df2' } ]
session object to be set
{ token: '268fc477-d4ee-4ed4-88cd-648539397df2' }
setting session for 268fc477-d4ee-4ed4-88cd-648539397df2 socket /#iEqqcIsBbATDs1a-AAAB
local reference after set
{ token: '268fc477-d4ee-4ed4-88cd-648539397df2',
socket: '/#iEqqcIsBbATDs1a-AAAB' }
realtime after set
[ {
token: '268fc477-d4ee-4ed4-88cd-648539397df2',
socket: '/#iEqqcIsBbATDs1a-AAAB'
} ]

Publicgist,也欢迎在这里评论。 我希望这个问题对其他人也有用。

编辑 Lodash referenceReturns the matched element, else undefined. 我不确定这是否意味着它 returns 克隆对象或引用查询对象。

发生的事情是您产生的值是一个对象,根据 co 文档,该对象会将对象中的每个值视为要解决的承诺,并且 return (新)具有相同键和值的对象是已解决承诺的值。

在您的情况下,由于属性的值(例如 token)不是承诺,因此值按原样传递,因此 returned 看起来 与您生成的那个一样,但实际上它是一个新对象,不是 realtime 里面的那个。 co 中创建这个新对象的代码是 here:

if (isObject(obj)) return objectToPromise.call(this, obj);

要防止这种情况发生,您需要做

let session = yield Promise.resolve(_.find(realtime, data => data.token === token));

如果您生成了一个标量值,co 会抱怨这不是可生成的。但是,由于您生成了一个对象值,co 将其解释为一个对象类型的可生成对象。这就提出了问题——为什么你首先要尝试产生不可产生的东西?

最后一点:

Lodash reference says Returns the matched element, else undefined. I am not sure if that means that it returns cloned object or reference to queried object.

当然,_.find return是找到的元素本身,而不是它的克隆。