我正在搜索,无法找到以ES6方式解决此问题的正确方法。
class MyClass {
// i can't event decalre _this/_self here
constructor() {
setTimeout(function(){
// other work..
hiUser(); // this.hiUser() or //_this.hiUser() not working
},1000);
}
hiUser(){
alert('Hi');
}
}
答案 0 :(得分:10)
之前的答案仅为您提供了如何修复它的代码示例;让我解释一下你的问题及其发生的原因
在您的代码示例中,setTimeout内部的函数被绑定到setTimeout的this
值(在严格模式下通常为window
或undefined
。
setTimeout(function () {
// this === window
}, 1000);
在ES6中,他们引入了lambda表达式(箭头函数),这些表达式是“ lexically bound ” - 这意味着他们从外部借用this
值范围。在你的情况下,这是类/对象。
为了利用 lambda表达式,它看起来像:
class Foo {
constructor () {
setTimeout(() => this.myMethod(), 1000);
}
myMethod () {
console.log('foo');
}
}
如果您使用Babel来转换代码并使用实验性功能,则可以使用ES7的绑定语法来解决您的问题。
如果绑定一个函数/方法,它会创建该函数的副本,并将this
值绑定到您选择的任何值。这将允许您使用将绑定到您的类/对象的function
语句。
<context to be bound> :: <function to receive context>
class Foo {
constructor () {
setTimeout(this::function() {
this.myMethod();
}, 1000);
}
myMethod () {
console.log('foo');
}
}
更短的版本看起来像下面的
constructor () {
setTimeout(this::this.myMethod, 1000);
}
如果你仍然有理解这个问题,我建议你阅读更多关于ES6课程和javascript绑定的内容。
答案 1 :(得分:3)
您可以使用fat arrow functions:
class MyClass {
constructor() {
setTimeout(() => {
this.hiUser();
}, 1000);
}
hiUser(){
alert('Hi');
}
}
或者你可以使用简单的ES5's Function.prototype.bind
method:
class MyClass {
constructor() {
setTimeout(function() {
this.hiUser();
}.bind(this), 1000);
}
hiUser(){
alert('Hi');
}
}
有ES7 proposal to shorthand the Function.prototype.bind
方法,因此,根据您(可能)使用的转换器(例如Babel或Typescript),您可以设置ES7标志并立即使用它:
class MyClass {
constructor() {
setTimeout(::function() {
this.hiUser();
}, 1000);
}
hiUser(){
alert('Hi');
}
}
答案 2 :(得分:-1)
setTimeout
可能有自己的this
上下文。您可以在构造函数中设置_self
,或使用箭头函数:
class MyClass {
constructor () {
var self = this;
// etc.
}
}