Phaser3游戏开发:嵌套媒体查询函数中跨类访问createMenu方法的报错解决
解决Phaser3中媒体查询函数访问类方法的
this指向问题 你遇到的Uncaught TypeError: Cannot read property 'createMenu' of undefined错误,本质是媒体查询函数里的this指向不对。默认情况下,普通函数作为事件回调执行时,this会指向调用它的window对象,而不是你的MenuScene实例,自然找不到父类BaseScene里的createMenu方法。
这里有几种简单可行的解决方案:
方案1:使用箭头函数(最推荐)
箭头函数不会绑定自己的this,而是继承外层作用域的this(也就是当前的MenuScene实例),直接替换普通函数即可:
class MenuScene extends BaseScene { create() { // 其他代码 // 把普通函数改成箭头函数 const mediaQuery = (x) => { if (x.matches) { this.createMenu2(gameState.menu, this.setupMenuEvents().bind(this)); } else { this.createMenu(gameState.menu, this.setupMenuEvents().bind(this)); } } let x = window.matchMedia("(max-width: 846px)"); mediaQuery(x); x.addEventListener("change", mediaQuery); } }
方案2:提前保存实例引用
在create方法里先把当前实例的this存到一个变量(比如self),然后在媒体查询函数里用这个变量代替this:
class MenuScene extends BaseScene { create() { // 其他代码 const self = this; // 保存当前MenuScene实例的引用 function mediaQuery(x) { if (x.matches) { self.createMenu2(gameState.menu, self.setupMenuEvents().bind(self)); } else { self.createMenu(gameState.menu, self.setupMenuEvents().bind(self)); } } let x = window.matchMedia("(max-width: 846px)"); mediaQuery(x); x.addEventListener("change", mediaQuery); } }
方案3:手动绑定this到函数
通过bind方法强制把媒体查询函数的this绑定到当前实例,不管是调用函数还是添加监听时都要绑定:
class MenuScene extends BaseScene { create() { // 其他代码 function mediaQuery(x) { if (x.matches) { this.createMenu2(gameState.menu, this.setupMenuEvents().bind(this)); } else { this.createMenu(gameState.menu, this.setupMenuEvents().bind(this)); } } let x = window.matchMedia("(max-width: 846px)"); mediaQuery.call(this, x); // 调用时绑定this到当前实例 x.addEventListener("change", mediaQuery.bind(this)); // 添加监听时绑定this } }
额外说明
关于this.setupMenuEvents().bind(this)这部分,如果setupMenuEvents方法内部也依赖MenuScene实例的this,建议在setupMenuEvents定义时就用箭头函数,或者在调用时提前绑定,避免后续出现类似的this问题。
内容的提问来源于stack exchange,提问作者GreatCoder
相关产品推荐
相关产品推荐

