H5(JavaScript/TypeScript)慎用constructor.name作標識

做個簡單的錯誤筆記,主要是使用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);
  1. 問題
    在開發和調試階段,沒有任何問題,比如登錄界面是可以正常刪除。但是一旦發佈出去。就出現不能刪除登錄界面的問題。
  2. 思考
    首先想到的是沒有正確刪除登錄對象,但是是通過打印,是有調用相關的方法。
    其次,應該是不能正確取出對應的登錄對象,所以無法正確刪除。
    因爲有用到構造函數名字作爲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代碼。那麼把類名改小是最好的辦法了。

發佈了91 篇原創文章 · 獲贊 72 · 訪問量 78萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章