实例化导出类时遇属性初始化错误:TypeError: Cannot set property '_db' of undefined
解决TypeError: Cannot set property '_db' of undefined的问题
嘿,这个问题我之前也碰到过!核心原因是你在mongodb.connect的普通回调函数里使用this时,它的指向已经不再是DB类的实例了——在Node.js的普通回调中,this默认指向全局对象(严格模式下就是undefined),所以才会报错说没法给undefined设置_db属性。
下面给你几种常用的解决办法,按推荐程度排序:
1. 使用箭头函数(最简洁推荐)
箭头函数不会创建自己的this上下文,它会继承外层作用域的this,也就是DB类的实例。直接把回调改成箭头函数就行:
const mongodb = require('mongodb').MongoClient const url = 'mongodb://localhost/via' const collection = 'images' module.exports = class DB { constructor() { mongodb.connect(url, (err, db) => { // 改成箭头函数 if (err) throw err this._db = db.db('via') this._db.createCollection(collection, (err, res) => { // 内部回调也可以同步改成箭头函数 if (err) throw err console.log('Collection created successfully!') }) }) } }
2. 提前保存this到变量
如果习惯用普通函数回调,可以在回调外部把实例的this存到一个变量(比如self或者that),然后在回调里用这个变量代替this:
const mongodb = require('mongodb').MongoClient const url = 'mongodb://localhost/via' const collection = 'images' module.exports = class DB { constructor() { const self = this; // 保存当前实例的this mongodb.connect(url, function(err, db) { if (err) throw err self._db = db.db('via') // 用self访问实例 self._db.createCollection(collection, function(err, res) { if (err) throw err console.log('Collection created successfully!') }) }) } }
3. 用bind()绑定this
你可以通过bind()方法把回调函数的this强制绑定到DB类的实例上:
const mongodb = require('mongodb').MongoClient const url = 'mongodb://localhost/via' const collection = 'images' module.exports = class DB { constructor() { mongodb.connect(url, function(err, db) { if (err) throw err this._db = db.db('via') this._db.createCollection(collection, function(err, res) { if (err) throw err console.log('Collection created successfully!') }) }.bind(this)) // 绑定this到当前实例 } }
额外推荐:用async/await替代回调
现在MongoDB驱动已经支持Promise了,用async/await写异步代码会更清晰,还能避免回调嵌套,同时this的指向也不会出问题:
const mongodb = require('mongodb').MongoClient const url = 'mongodb://localhost/via' const collection = 'images' module.exports = class DB { constructor() { // 调用异步初始化方法,注意constructor不能直接是async函数 this.initDatabase() } async initDatabase() { try { const client = await mongodb.connect(url) this._db = client.db('via') await this._db.createCollection(collection) console.log('Database and collection setup completed!') } catch (err) { console.error('Failed to initialize database:', err) throw err } } }
内容的提问来源于stack exchange,提问作者Francisco
相关产品推荐
相关产品推荐

