做个简单的错误笔记,主要是使用js的原型构造函数名字作为唯一key引起的错误。
开发语言:TypeScript/JavaScript
开发工具:白鹭工具和引擎(Egret)
prototype.constructor.name引起的错误
最近在做项目写底层的时候,为了底层的通讯和便捷性,预先缓存了类(构造函数),其中有一种方式,是通过prototype.constructor.name来作为key绑定某些数据结构,同时也用构造函数(类名)在底层做自动注入相关属性。
其中是获取构造函数的代码
static getClassName(clazz:any):string
{
return clazz.prototype.constructor.name;
}
//用法
ClassUtils.getClassName(LoginView);
- 问题
在开发和调试阶段,没有任何问题,比如登录界面是可以正常删除。但是一旦发布出去。就出现不能删除登录界面的问题。 - 思考
首先想到的是没有正确删除登录对象,但是是通过打印,是有调用相关的方法。
其次,应该是不能正确取出对应的登录对象,所以无法正确删除。
因为有用到构造函数名字作为key,凭感觉想到是这里出了问题。所以打印了一下信息。
本地正常调试的构造函数名字:
发现莫名其妙打印出i的构造函数。错误应该是这里的。再加强打印信息,就明白错误的根源了。
可以看到deubg调试中的LoginView之类的类,已经被打包工具改造成i等最简写的字母了。
所以,除非手动输入名字作为key,万万是不能由程序自动获取的。(AS3,java等语言是可以这样做的)
仔细查找一下编译的.min.js代码,确定这个问题了。编译的后的js代码
ClassUtils.getClassName=function(t,e){void 0===e&&(e=!1);var i=t.prototype.constructor.name;return e?asf.StringUtils.uncapitalize(i):i}
原TS代码
/**
* 获取到Class的名字(不包含包名).
* 这个方法要注意,因为打包成min.js的时候,会修改类名,所以到时无法获真实的类名字了
* @param clazz 构造函数实例
* @param firstMin 名字的首字母是否小写。默认是不修改
* @returns {string} 返回名字
*/
static getClassName(clazz:any,firstMin:boolean = false):string
{
var name:string = clazz.prototype.constructor.name;
if(firstMin)
{
//首字母变小写
return StringUtils.uncapitalize(name);
}
return name;
}
由于打包工具为了最大可能地减小js文件的体积大小,所以会尽可能地压缩js代码。那么把类名改小是最好的办法了。