ES6 如何在 class 中获取 _this,在另一个上下文中
ES6 How to get _this inside class, inside another context
我正在搜索,但找不到以 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');
}
}
您可以使用 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');
}
}
setTimeout
可能有自己的 this
上下文。不过,您可以在构造函数中设置 _self
,或使用箭头函数:
class MyClass {
constructor () {
var self = this;
// etc.
}
}
之前的答案只给了你如何修复它的代码示例;让我解释一下您的问题及其发生的原因
在您的代码示例中,setTimeout 中的函数被绑定到 setTimeout 的 this
值(在严格模式下通常为 window
或 undefined
)。
setTimeout(function () {
// this === window
}, 1000);
在 ES6 中,他们引入了“词法绑定”的 lambda 表达式(箭头函数)——这意味着他们借用了 this
来自外部范围的值。在你的例子中,就是 class/object.
为了利用 lambda 表达式s,它看起来像:
class Foo {
constructor () {
setTimeout(() => this.myMethod(), 1000);
}
myMethod () {
console.log('foo');
}
}
如果您使用 Babel 来转译您的代码,并且正在使用实验性功能,您也可以使用 ES7 的 binding 语法来解决您的问题。
如果您绑定 function/method,它会创建该函数的副本,并将 this
值绑定到您选择的任何值。这将允许您使用将绑定到您的 class/object.
的 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 绑定的内容。
我正在搜索,但找不到以 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');
}
}
您可以使用 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');
}
}
setTimeout
可能有自己的 this
上下文。不过,您可以在构造函数中设置 _self
,或使用箭头函数:
class MyClass {
constructor () {
var self = this;
// etc.
}
}
之前的答案只给了你如何修复它的代码示例;让我解释一下您的问题及其发生的原因
在您的代码示例中,setTimeout 中的函数被绑定到 setTimeout 的 this
值(在严格模式下通常为 window
或 undefined
)。
setTimeout(function () {
// this === window
}, 1000);
在 ES6 中,他们引入了“词法绑定”的 lambda 表达式(箭头函数)——这意味着他们借用了 this
来自外部范围的值。在你的例子中,就是 class/object.
为了利用 lambda 表达式s,它看起来像:
class Foo {
constructor () {
setTimeout(() => this.myMethod(), 1000);
}
myMethod () {
console.log('foo');
}
}
如果您使用 Babel 来转译您的代码,并且正在使用实验性功能,您也可以使用 ES7 的 binding 语法来解决您的问题。
如果您绑定 function/method,它会创建该函数的副本,并将 this
值绑定到您选择的任何值。这将允许您使用将绑定到您的 class/object.
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 绑定的内容。