我們很容易被漂亮的代碼吸引,也不知不覺的在自己的程式碼程式庫中加入這些。卻沒有冷靜的想過它們的優劣。這不,我就收集了一系列形如 "是否為……?" 的判斷的boolean函數。
isNull: function(a){return a === null;},isUndefined: function(a){return a === undefined;},isNumber: function(a){return typeof a === 'number';},isString: function(a){return typeof a === 'string';},isBoolean: function(a){return typeof a === 'boolean';},isPrimitive: function(b){var a = typeof b;return !!(b === undefined || b === null || a == 'boolean' || a == 'number' || a == 'string');},isArray: function(a){return proto_obj.toString.call(a) === '[object Array]';},isFunction: function(a){return proto_obj.toString.call(a) === '[object Function]';},isPlainObject: function(o){if (!o || o === win || o === doc || o === doc.body) {return false;}return 'isPrototypeOf' in o && proto_obj.toString.call(o) === '[object Object]';},isWindow: function(o){return o && typeof o === 'object' && 'setInterval' in o;},isEmptyObject: function(o){ for(var a in o) {return false; } return true;}
以上isXX系列中,isUndefined在類庫中用的最多。如判斷是否傳入了某個參數,判斷對象是否擁有某個屬性等等。但這個函數是不必存在,我已將其移除。理由如下
- isUndefined 與 使用全等(===)或typeof 多了一層函數調用。很明顯多一層函數調用比直接使用原生的運算子效率會低(雖然有些微不足道),但如果isUndefined調用次數很多如上萬次還是很 明顯的。我曾經在郵箱架構中加入了該函數,調用次數有4000多次,從效能分析工具看佔用了近1%的時間。僅僅一個判斷佔1%的調用時間還是很可怕的。當 然,郵箱架構內的isUndefined處在多層閉包的頂層,訪問其也會佔用較多時間。如果這一條還不足以讓你放棄isUndefined,請看下面。
- 函數從一定程度上是對一些代碼的封裝,抽象。是組織良好代碼的方式之一,且有利於降低代碼的複雜性。但isNull/isUndefined/isBoolean/isNumber/isString函數內僅有一句,抽象層次很低。因此完全不必封裝而提取出一個函數。
- isUndefined(a) 與 a === undefined相比並不會節省幾個位元組(呵,你可以命名的更短但損失了可讀性)。
綜上,我去掉了類庫中對基本類型判斷的isNull/isUndefined/isBoolean/isNumber/isString,需要用到這些判斷的時候直接使用typeof運算子等。