每當我從我的 mongo 資料庫中檢索一個物件時,它都沒有任何方法,我試圖找出 (1) 原因和 (2) 解決方案。
總結一下,下面總結一下這個問題:
(1) 我可以創建一個物件并且它的方法起作用:
const newUser = new User(email, hashedPassword);
console.log(newUser.test); // correct - it’s not undefined
(2) 我可以將實體(及其方法)插入資料庫(通過saveToDb):
const insertedUser = await collection.insertOne(this);
(3) 我可以從資料庫中檢索它(通過findByEmail):
const user = await collection.findOne({ email });
(4) 但它不再有任何方法了:
if (!user) return; // temporary code
console.log(user); // correctly displays object keys and values
console.log('user.test', user.test); // undefined - why?
為什么會這樣?我已經閱讀了一些關于它的其他帖子,但它們似乎都使用貓鼬,我沒有在我的應用程式中使用它(也許我應該使用它?)。這篇文章沒有得到答案,我認為這是一個類似的問題。
任何見解將不勝感激,謝謝。
萬一需要看,這里是類:
export class User {
email: string;
hashedPassword: any;
dateCreated: Date;
constructor(email: string, hashedPassword: any) {
this.email = email; // make email.toLowerCase();
this.hashedPassword = hashedPassword;
this.dateCreated = new Date();
}
async saveToDb() {
try {
const collection = getCollection(USERS_COLLECTION_NAME);
const sanitisedEmail = this.email.toLowerCase();
const insertedUser = await collection.insertOne(this);
console.log('THIS HAS BEEN INSERTED TO DB:', this);
console.log('this.test:', this.test); // works
this.test();
const token = jwt.sign(insertedUser, sanitisedEmail, {
expiresIn: 60 * 24,
});
return token;
} catch (err) {
throw err;
}
}
test() {
console.log('test() within class Fn');
return 5;
}
static staticTest() {
console.log('staticTest() within class Fn');
return 6;
}
signToken() {
const token = jwt.sign(this, this.email, {
expiresIn: 60 * 24,
});
return token;
}
static async fetchAll() {
try {
const collection = getCollection(USERS_COLLECTION_NAME);
const users = await collection.find().toArray();
return users;
} catch (err) {
throw err;
}
}
static async findByEmail(email: string) {
try {
const collection = getCollection(USERS_COLLECTION_NAME);
const user = await collection.findOne({ email });
if (!user) return; // temporary code
console.log('FOUND THIS USER: ', user); // works
console.log('user.test', user.test); // undefined - key problem lies here...
return user;
} catch (err) {
throw err;
}
}
}
uj5u.com熱心網友回復:
您通過查詢方法回傳的物件,例如findOne,將是普通物件。它們不是您的類的實體,因為這些物件是作為 JSON 發送并保存在資料庫中的,這不包括類資訊、原型或方法。
所以你可以做的是改變你得到的物件的原型。或者更好的是,創建一個類的新實體 Object.create并注入屬性Object.assign:
const user = Object.assign(
Object.create(User.prototype),
await collection.findOne({ email })
);
現在您的user物件將再次可以訪問原型方法。
為了完整起見,我還將提到替代方案:
const user = await collection.findOne({ email });
Object.setPrototypeOf(user, User.prototype);
但是請閱讀 Mozilla 貢獻者在setPrototypeOf上提供的免責宣告:
根據現代 JavaScript 引擎如何優化屬性訪問的本質,更改物件的 [[Prototype]] 目前在每個瀏覽器和 JavaScript 引擎中都是非常緩慢的操作。此外,更改繼承的影響是微妙而廣泛的,并且不僅限于在
Object.setPrototypeOf(...)陳述句中花費的時間,還可能擴展到可以訪問任何 [[Prototype]] 已更改的物件的任何代碼。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/489216.html
標籤:javascript 节点.js mongodb 猫鼬
