【发布时间】:2017-05-11 08:45:13
【问题描述】:
我觉得这很麻烦。我可能做错了,或者有一些我不知道的更简单的方法(在不知道要搜索什么的情况下找不到太多)。
我想避免执行以下两种变通方法,以确保 this 正确指向我的方法中的 DB 类:
this.connect = this.connect.bind(this);
db.connect.bind(db)
数据库类:
'use strict';
const http = require('http');
const MongoClient = require('mongodb').MongoClient;
class DB {
constructor(opts){
this.opts = opts;
this.dbUrl = process.env.MONGODB_URL;
// anyway to avoid this hacK?
this.connect = this.connect.bind(this);
this.close = this.close.bind(this)
}
async connect(ctx, next){
try {
ctx.db = await MongoClient.connect(this.dbUrl); // fixes `this` being incorrect here
} catch(err) {
ctx.status = 500;
ctx.body = err.message || http.STATUS_CODES[ctx.status];
}
await next();
}
async close(ctx, next){
const result = await ctx.db.close();
await next();
}
}
module.exports = DB;
调用DB类方法db.connect():
'use strict';
const Koa = require('koa');
const DB = require('./db');
const db = new DB();
const bodyParser = require('koa-bodyparser');
const router = require('koa-router');
const api = router();
const app = new Koa();
const cors = require('kcors');
app
.use(bodyParser())
.use(cors())
.use(db.connect); // the above constructor copying fixes having to do `db.connect.bind(db)` here
// without the constructor fix in class DB:
.use(db.connect.bind(db)) // this gets annoying having to do this everywhere
哪个更“正确”或者是否有第三种方法可以避免这两种解决方法?如果只有这两种方法可以将类方法绑定到它们的类,那么每种方法的优缺点是什么。
【问题讨论】:
-
另一种不那么骇人听闻的方式是在外壳中,即
app.use((...args) => db.connect(...args)) -
在
async connect(){}方法中正确获取this似乎非常冗长......如果我理解正确,仍然不会将其更改为DB -
严肃的问题:使用
bind()真的被认为是一种黑客行为吗?我一直认为这是在丢失上下文时绑定上下文的好方法。我知道替代方法是使用胖箭头函数(() => {...})或将上下文分配给您通过闭包访问的变量(例如,var context或var _this或var that或var self)...但是对于我,bind()通常是最简洁合理的方式。 -
这是我被告知的“正确”方式(不知道这种特定情况是否适用于“最好/最简单的方式”),但是当每个当您在代码库中调用类实例的方法时,您必须将其绑定到自身。
-
@chovy 我想你可能会觉得stackoverflow.com/a/32192892/3814251 是一个有趣的潜在解决方案
标签: javascript ecmascript-6 es6-class