为什么我的ES6(使用Babel)类说"this"在实例方法中未定义? [英] Why does my ES6 (using Babel) class say `this` is undefined in an instance method?
问题描述
我正在使用Hapi.JS在Node中构建应用程序.
I am building an application in Node using Hapi.JS.
我有一个用于身份验证插件的类,它给我带来各种各样的问题.当我尝试从类的方法中引用this
时,出现一条错误消息,提示未定义this
.为什么会这样?
I have a class for an authentication plugin that is giving me all sorts of problems. When I attempt to reference this
from within a method on the class, I get an error saying that this
is undefined. Why is this happening?
摘录:
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);
每次调用寄存器函数时,都会收到此错误:
Every time the register function is called, I receive this error:
TypeError: Cannot set property 'server' of undefined
为什么我的实例不起作用?
Why on earth is my instance not working?
推荐答案
带有babel的ES6类不会为您自动绑定this
.自引入class
以来,这是一个常见的误解.有多种解决方法.
ES6 class with babel doesn't autobind this
for you. This is a common misconception since class
was introduced. There are multiple ways to solve it.
-
使用ES7. Babel有一个实验性的(截至本文), class-properties 插件.
class OAuth {
constructor () {}
register = (server, err, next) => {
this.server = server
this.registerRoutes()
}
registerRoutes = () => {}
}
这是如何工作的?当您将箭头功能与class-properties插件一起使用时,它会转换为如下所示的内容,并在您使用class
语法时按预期进行绑定.
How does this work? When you use arrow-functions along with the class-properties plugin, it gets transformed to something like the following, binding this as you expect when you use class
syntax.
var OAuth = function OAuth() {
var _this = this;
_classCallCheck(this, OAuth);
this.register = function (server, err, next) {
_this.server = server;
_this.registerRoutes();
};
this.registerRoutes = function () {};
}
-
在构造函数中绑定类属性
Bind your class properties in the constructor
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用于其class属性绑定魔术.我们不创建反应组件.
Use createClass
from react, which does the binding for you. Note we're only using react for its class property binding magic. We are not creating react components.
import React from 'react'
const OAuth = React.createClass({
register (server, err, next) {
this.server = server
this.registerRoutes()
}
registerRoutes () {}
})
仅使用反应类中的autoBind
.在这里,我们使用ES6 +类语法来制作React组件,只是为了使用autoBind
方法.我们不必使用带有响应组件的componentWillMount
,render
等.
Use only autoBind
from react-class. Here we're making a react component using ES6+ class syntax just to use the autoBind
method. We don't have to use componentWillMount
, render
, etc, which are provided with react components.
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基本相同,可能也减少了代码.
Roll your own class property binder. It's a nice exercise, basically the same as option 2, possibly less code as well.
// 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);
})
}
如果您确实想创建react组件,则可以结合使用箭头功能和属性初始化程序来做类似的事情
If you actually want to create react components, you can combine arrow-functions and property initializers to do something like
class OAuthComponent extends React.Component {
whateverMethodYouWant = (event) => {
this.setState({somePropertyYouCareAbout: true}) // this is bound
}
anotherMethod = () => {
this.whateverMethodYouWant() // this is bound
}
}
这篇关于为什么我的ES6(使用Babel)类说"this"在实例方法中未定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!