传播语法 returns 意外的对象
Spread syntax returns unexpected object
我正在使用节点并且我已经使用过。
babel-node
"start": "nodemon --exec babel-node --presets es2015 index.js"
我的传播语法没有按预期工作。这是我的代码。
export const login = async (parentValue, { email, password }) => {
try {
const user = await User.findOne({
email
});
console.log(user);
if (!user.authenticateUser(password)) {
throw new Error('Wrong password');
}
const dummyObject = {
...user
};
console.log({ dummyObject });
return { ...user };
} catch (e) {
console.log(e);
throw new Error(e.message);
}
};
我用过的那行console.log(user)
,效果很好。
它 returns
{
id: xxx,
name: xxxx
}
而且我在 console.log(dummyObject)
上得到了意想不到的数据;
这是我得到的。
{ jojo:
{ '$__':
InternalCache {
strictMode: true,
selected: {},
shardval: undefined,
saveError: undefined,
validationError: undefined,
adhocPaths: undefined,
removing: undefined,
inserting: undefined,
saving: undefined,
version: undefined,
getters: {},
_id: 5c798295f53323b34cabf1ca,
populate: undefined,
populated: undefined,
wasPopulated: false,
scope: undefined,
activePaths: [Object],
pathsToScopes: {},
cachedRequired: {},
session: undefined,
ownerDocument: undefined,
fullPath: undefined,
emitter: [Object],
'$options': [Object] },
isNew: false,
errors: undefined,
_doc:
{ _id: 5c798295f53323b34cabf1ca,
fullName: 'sarmad',
password: 'a$c.XDX75ORXYA4V/hUXWh.usVf2TibmKfY.Zpu3cpTssFaYvsGyhte',
email: 'sarmad@gmail.com',
createdAt: 2019-03-01T19:05:57.454Z,
updatedAt: 2019-03-01T19:05:57.454Z,
__v: 0 },
'$init': true } }
我是不是做错了什么?从技术上讲,它应该 return 用户对象
注意:我不想使用 Object.assign
看起来您正在使用 mongoose,而且您似乎正在使用展开运算符获取 mongoose 对象属性。您需要转换为 JSON 才能摆脱这些。
尝试:
const dummyObject = { ...user.toJSON() };
您还可以:
const dummyObject = { ...user.toObject() };
^ 这可能是首选方式
另一种解决方案是在进行查询时只请求普通对象。例如:
Schema.findOne(query).lean()
这将 return 一个普通对象而不是猫鼬对象。
你得到不同的日志,因为 mongoose 使用自定义检查功能
在节点中试试这个:
const obj = {
[Symbol.for('nodejs.util.inspect.custom')]() {
return "totally not an object";
}
}
console.log(obj); // "totally not an object"
因为 mongoose inspect
是在对象的原型上定义的,所以当您使用 ...
时它不会被复制,因为 spread 只复制对象自己的属性。
class Obj {
[Symbol.for('nodejs.util.inspect.custom')]() {
return "totally not an object";
}
}
const obj = new Obj();
const obj2 = { ...obj };
console.log(obj); // "totally not an object"
console.log(obj2); // {}
您可以通过为复制的对象设置原型来修复它:
Reflect.setPrototypeOf(obj2, Reflect.getPrototypeOf(obj))
但是由于您正在处理自定义对象,因此不应真正使用对象传播。 Spread 仅对 POJO 是安全的。否则你可能会很容易陷入麻烦(有隐藏的 props、getters、setters 和原型地狱)
https://repl.it/repls/ToughModestInstructionset
https://github.com/Automattic/mongoose/blob/master/lib/document.js#L2853:L2869
我正在使用节点并且我已经使用过。
babel-node
"start": "nodemon --exec babel-node --presets es2015 index.js"
我的传播语法没有按预期工作。这是我的代码。
export const login = async (parentValue, { email, password }) => {
try {
const user = await User.findOne({
email
});
console.log(user);
if (!user.authenticateUser(password)) {
throw new Error('Wrong password');
}
const dummyObject = {
...user
};
console.log({ dummyObject });
return { ...user };
} catch (e) {
console.log(e);
throw new Error(e.message);
}
};
我用过的那行console.log(user)
,效果很好。
它 returns
{
id: xxx,
name: xxxx
}
而且我在 console.log(dummyObject)
上得到了意想不到的数据;
这是我得到的。
{ jojo:
{ '$__':
InternalCache {
strictMode: true,
selected: {},
shardval: undefined,
saveError: undefined,
validationError: undefined,
adhocPaths: undefined,
removing: undefined,
inserting: undefined,
saving: undefined,
version: undefined,
getters: {},
_id: 5c798295f53323b34cabf1ca,
populate: undefined,
populated: undefined,
wasPopulated: false,
scope: undefined,
activePaths: [Object],
pathsToScopes: {},
cachedRequired: {},
session: undefined,
ownerDocument: undefined,
fullPath: undefined,
emitter: [Object],
'$options': [Object] },
isNew: false,
errors: undefined,
_doc:
{ _id: 5c798295f53323b34cabf1ca,
fullName: 'sarmad',
password: 'a$c.XDX75ORXYA4V/hUXWh.usVf2TibmKfY.Zpu3cpTssFaYvsGyhte',
email: 'sarmad@gmail.com',
createdAt: 2019-03-01T19:05:57.454Z,
updatedAt: 2019-03-01T19:05:57.454Z,
__v: 0 },
'$init': true } }
我是不是做错了什么?从技术上讲,它应该 return 用户对象 注意:我不想使用 Object.assign
看起来您正在使用 mongoose,而且您似乎正在使用展开运算符获取 mongoose 对象属性。您需要转换为 JSON 才能摆脱这些。
尝试:
const dummyObject = { ...user.toJSON() };
您还可以:
const dummyObject = { ...user.toObject() };
^ 这可能是首选方式
另一种解决方案是在进行查询时只请求普通对象。例如:
Schema.findOne(query).lean()
这将 return 一个普通对象而不是猫鼬对象。
你得到不同的日志,因为 mongoose 使用自定义检查功能
在节点中试试这个:
const obj = {
[Symbol.for('nodejs.util.inspect.custom')]() {
return "totally not an object";
}
}
console.log(obj); // "totally not an object"
因为 mongoose inspect
是在对象的原型上定义的,所以当您使用 ...
时它不会被复制,因为 spread 只复制对象自己的属性。
class Obj {
[Symbol.for('nodejs.util.inspect.custom')]() {
return "totally not an object";
}
}
const obj = new Obj();
const obj2 = { ...obj };
console.log(obj); // "totally not an object"
console.log(obj2); // {}
您可以通过为复制的对象设置原型来修复它:
Reflect.setPrototypeOf(obj2, Reflect.getPrototypeOf(obj))
但是由于您正在处理自定义对象,因此不应真正使用对象传播。 Spread 仅对 POJO 是安全的。否则你可能会很容易陷入麻烦(有隐藏的 props、getters、setters 和原型地狱)
https://repl.it/repls/ToughModestInstructionset
https://github.com/Automattic/mongoose/blob/master/lib/document.js#L2853:L2869