我遇到了这个问题,我找不到任何解决方案,也许你们可以帮忙?
为什么我不能访问this._activeScene?即使我已经为此设置了一个值,它也总是返回undefined。_activeScene
class SceneManager {
constructor() {
this._activeScene = null;
}
init() {
let loop = setInterval(function() {
console.log(this._activeScene);
// Returns undefined.
if(this._activeScene != null) {
const self = this._activeScene;
self.options.update();
self.options.render();
}
}, 16.66);
}
setScene(scene) {
this._activeScene = scene;
this._activeScene.options.initialize()
}
get activeScene() {return this._activeScene;}
}
let sceneManager = new SceneManager();
sceneManager.init();
let gameScene = new Scene();
sceneManager.setScene(gameScene);
答案 0 :(得分:2)
所以这是范围的问题,当您创建匿名函数时,它在全局范围E.G function(){};
中,而不是类实例的范围。
这是使用箭头功能() => {}
的情况之一,因为它们在创建它们的作用域中运行,但是,箭头功能是ES6功能,因此如果您需要在没有ES6的情况下使用它,则可以使用{{3 }}方法
ES6版本
let loop = setInterval(()=>{ // using arrow functions
console.log(this._activeScene);
// Returns undefined.
if(this._activeScene != null) {
const self = this._activeScene;
self.options.update();
self.options.render();
}
}, 16.66); // not sure you can have 16.66 milliseconds
非ES6使用.bind
let loop = setInterval((function() {
console.log(this._activeScene);
// Returns undefined.
if(this._activeScene != null) {
const self = this._activeScene;
self.options.update();
self.options.render();
}
}).bind(this), 16.66);
// using .bind create a pointer to the function in the scope of the given var
// so in this case we're putting the function in the scope of this
// not sure you can have 16.66 milliseconds
答案 1 :(得分:-1)
this
不是类实例。这里的问题是范围。
最实际的正确解决方案是使用箭头函数,它们不绑定自己的作用域,而是从父对象继承(在本例中为SceneManager的实例)。
代码如下:
class SceneManager {
constructor() {
this._activeScene = null;
}
init() {
// As suggested by Liam
// ES6 arrow functions will automatically inherit the current scope
// as their scope
let loop = setInterval(() => {
console.log(this._activeScene);
// Will no longer output undefined, will output null instead
if(this._activeScene != null) {
const self = this._activeScene;
self.options.update();
self.options.render();
}
}, 16.66);
}
setScene(scene) {
this._activeScene = scene;
this._activeScene.options.initialize()
}
get activeScene() {return this._activeScene;}
}
let sceneManager = new SceneManager();
sceneManager.init();
let gameScene = new Scene();
sceneManager.setScene(gameScene);
其他“较旧”的解决方案是使用let that = this;
技巧,这是一种众所周知的转移范围的方法。
class SceneManager {
constructor() {
this._activeScene = null;
}
init() {
let that = this;
let loop = setInterval(function() {
console.log(that._activeScene);
// now outputs null
if(that._activeScene != null) {
const self = that._activeScene;
self.options.update();
self.options.render();
}
}, 16.66);
}
setScene(scene) {
this._activeScene = scene;
this._activeScene.options.initialize()
}
get activeScene() {return this._activeScene;}
}
let sceneManager = new SceneManager();
sceneManager.init();
let gameScene = new Scene();
sceneManager.setScene(gameScene);