我正在使用Hapi.JS在Node中构建应用程序。
我有一个认证插件类,它给了我各种各样的问题。当我尝试从类中的方法中引用this
时,我收到一条错误消息,指出this
未定义。为什么会这样?
摘录:
class OAuth {
constructor () {}
register (server, err, next) {
this.server = server;
this.registerRoutes();
}
registerRoutes () {
console.log(this.server.route);
this.server.route([
{
method: 'POST',
path: '/oauth/token',
config: {
auth: false,
handler: function(request,reply){
console.log("test");
reply("test");
}
}
},
{
method: 'GET',
path: '/test',
config: {
auth: false,
handler: function(request,reply){
console.log("test");
reply("test");
}
}
}
]);
}
}
module.exports = new OAuth();
在其他地方,这被称为:
const oauth = require('./oauth');
oauth.register(server);
每次调用寄存器功能时,都会收到此错误:
TypeError: Cannot set property 'server' of undefined
为什么我的实例不起作用?
答案 0 :(得分:12)
带有babel的ES6课程不会为您自动提问this
。自class
引入以来,这是一种常见的误解。有多种方法可以解决它。
使用ES7。 Babel有一个实验性的(截至本文)class-properties插件。
class OAuth {
constructor () {}
register = (server, err, next) => {
this.server = server
this.registerRoutes()
}
registerRoutes = () => {}
}
这是如何工作的?当您使用箭头函数以及类属性插件时,它会转换为类似下面的内容,并在您使用class
语法时按预期绑定它。
var OAuth = function OAuth() {
var _this = this;
_classCallCheck(this, OAuth);
this.register = function (server, err, next) {
_this.server = server;
_this.registerRoutes();
};
this.registerRoutes = function () {};
}
在构造函数
中绑定您的类属性class OAuth {
constructor () {
// `this` is the OAuth instance in the constructor
this.register = this.register.bind(this)
this.registerRoutes = this.registerRoutes.bind(this)
}
register (server, err, next) {
// `this` is the global object.. NOT!
// after binding in the constructor, it's the OAuth instance ^_^
// provided you use `new` to initialize your instance
this.server = server
this.registerRoutes()
}
registerRoutes () {}
}
使用来自react的createClass
,它会为您执行绑定。注意我们只对其类属性绑定魔法使用react。我们不会创建反应组件。
import React from 'react'
const OAuth = React.createClass({
register (server, err, next) {
this.server = server
this.registerRoutes()
}
registerRoutes () {}
})
仅使用react-class中的autoBind
。这里我们使用ES6 +类语法制作一个react组件,只是为了使用autoBind
方法。我们不必使用随反应组件提供的componentWillMount
,render
等。
import { autoBind } from 'react-class'
class OAuth extends React.Component {
constructor(props) {
super(props)
autoBind(this)
}
register (server, err, next) {
this.server = server
this.registerRoutes()
}
registerRoutes () {}
}
滚动您自己的类属性绑定器。这是一个很好的练习,基本上与选项2相同,也可能是更少的代码。
// call it in your constructor
bindStuff(this, ['register', 'registerRoutes', 'etc'])
// define it somewhere as
function bindStuff (context, props) {
props.forEach(prop => {
context[prop] = context[prop].bind(context);
})
}
如果您确实想要创建反应组件,可以将箭头函数和属性初始值设定项组合起来执行类似
的操作class OAuthComponent extends React.Component {
whateverMethodYouWant = (event) => {
this.setState({somePropertyYouCareAbout: true}) // this is bound
}
anotherMethod = () => {
this.whateverMethodYouWant() // this is bound
}
}