做個簡單的錯誤筆記,主要是使用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代碼。那麼把類名改小是最好的辦法了。