如何在LoadAssets中访问AssetLoadedFunc属性?TS/JS报错排查
问题解答:LoadAssets中访问AssetLoadedFunc属性的方法及适用语言
首先明确:这个问题同时适用于TypeScript和JavaScript,核心是函数执行时的this上下文丢失问题,这是两者共有的原型链/函数上下文机制导致的。
报错原因分析
你看到的ERROR TypeError: Cannot read property 'AssetLoaded' of null,本质是当AssetLoaded作为回调被传给LoadWidgetFromURL时,函数的this指向丢失了——默认情况下,回调函数执行时this会指向全局对象(浏览器中是window)或者null(严格模式下),而不是你的类实例,所以无法访问this.AssetLoaded。
解决方案
下面提供几种可靠的修复方式,同时解决访问AssetLoaded属性的问题:
1. 使用箭头函数绑定上下文(推荐)
箭头函数会自动捕获外部作用域的this,确保回调执行时this指向你的类实例。你可以在传递回调时用箭头函数包裹,或者直接把AssetLoaded定义为箭头函数:
方式1:包裹回调
LoadAssets(callback, user_data) { this.glg.LoadWidgetFromURL( "assets/Js/scrollbar_h.g", null, (glg_object, data) => this.AssetLoaded(glg_object, data), // 箭头函数保留this { name: "scrollbar_h", callback: callback, user_data: user_data } ); }
方式2:将AssetLoaded定义为箭头函数
// 类中直接定义为箭头函数 AssetLoaded = (glg_object, data) => { if (data.name == "scrollbar_h") { if (glg_object != null) glg_object.SetResourceObject("$config/GlgHScrollbar", glg_object); } else console.error("Unexpected asset name"); // 此时this指向类实例,可以正常访问AssetLoaded的属性 if (!this.AssetLoaded.num_loaded ) this.AssetLoaded.num_loaded = 1; else ++this.AssetLoaded.num_loaded; }
2. 使用bind方法强制绑定this
在传递回调时,用bind(this)将函数的this强制绑定到类实例:
LoadAssets(callback, user_data) { this.glg.LoadWidgetFromURL( "assets/Js/scrollbar_h.g", null, this.AssetLoaded.bind(this), // 绑定this到当前实例 { name: "scrollbar_h", callback: callback, user_data: user_data } ); }
注意:bind会返回一个新函数,如果需要解绑回调,最好提前保存这个绑定后的函数引用,避免重复绑定导致的问题。
3. 优化属性存储方式(更规范)
你目前把num_loaded挂在AssetLoaded函数本身,其实更符合类设计的方式是将它作为类的实例属性,这样不需要依赖函数的属性,也更易维护:
class YourComponent { // 定义为实例属性 private num_loaded = 0; LoadAssets(callback, user_data) { this.glg.LoadWidgetFromURL( "assets/Js/scrollbar_h.g", null, this.AssetLoaded.bind(this), { name: "scrollbar_h", callback: callback, user_data: user_data } ); } AssetLoaded(glg_object, data) { if (data.name == "scrollbar_h") { if (glg_object != null) glg_object.SetResourceObject("$config/GlgHScrollbar", glg_object); } else console.error("Unexpected asset name"); // 直接操作实例属性 this.num_loaded++; } }
内容的提问来源于stack exchange,提问作者Rahul Dapke
相关产品推荐
相关产品推荐

