问题是this
使用 JavaScript 时有点令人困惑,但是可以将其视为当前上下文。
例如,当您的代码在浏览器控制台中运行或不在其他函数中运行时this
是全球性的window
目的。当您直接在控制器中时connect
method this
是控制器的实例。
但是,当您将函数传递给Peaks.init
该函数创建了它自己的新上下文,其中this
是函数的上下文,不再是控制器实例。
调用时有三种常见的解决方法this.setSegments
;
1.设置一个函数作用域之外的变量
根据您的解决方案,const setSegments = this.setSegments;
之所以有效,是因为您正在函数范围之外创建引用,并且函数可以访问它。
connect() {
const options = {}: // ... Options
// this is the controller's instance
const setSegments = this setSegments;
Peaks.init(options, function (err, peaks) {
// this is the peaks init handler context
window.instance = peaks;
// this.setSegments(): - will not work
setSegments();
instance.on('segments.enter', function (segment) {
// this is the event (usually)
});
});
}
2. 使用bind覆盖函数的this
您可以将函数拉出到变量中,然后添加.bind(this)
以便在调用该函数时它将使用控制器实例中的 this 。
connect() {
const options = {}: // ... Options
// this is the controller's instance
const myFunction = function (err, peaks) {
// this is the BOUND this provided by the bind command and will be the controller's instance
window.instance = peaks;
this.setSegments():
instance.on('segments.enter', function (segment) {
// this is the event (usually)
});
};
myFunction.bind(this);
Peaks.init(options, myFunction);
}
3.使用箭头函数(最简单)
您应该能够在现代浏览器中使用箭头函数,或者如果您有一个正在运行的构建工具,它可能会将其转译为旧版浏览器。
代替function() {}
你用() => {}
它抓住了this
相反,来自父函数上下文。
connect() {
const options = {}: // ... Options
// this is the controller's instance
Peaks.init(options, (err, peaks) => {
// this is now the controller's instance and NOT the peak handler context
window.instance = peaks;
this.setSegments():
instance.on('segments.enter', function (segment) {
// this is the event (usually) and is NOT the controller instance as arrow function not used here.
});
});
}
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this更多细节