代码改变世界

淘宝Kissy框架分析【四】

2010-06-15 12:00  BlueDream  阅读(3345)  评论(0)    收藏  举报

今天开始分析kissy-lang.js

源码如下:

/**
 * @module    j1616-lang
 * @author    liangchaoyjs@163.com
 
*/
 J1616.add(
'j1616.lang'function(J, undefined) {
    
    
var win = window, doc = document, loc = location,
        AP 
= Array.prototype,
        indexOf 
= AP.indexOf, filter = AP.filter,
        trim 
= String.prototype.trim,
        toString 
= Object.prototype.toString,
        encode 
= encodeURIComponent,
        decode 
= decodeURIComponent,
        REG_TRIM 
= /^\s+|\s+$/g,
        REG_ARR_KEY 
= /^(\w+)\[\]$/,
        REG_NOT_WHITE 
= /\S/;

    J.mix(J, {
        isBoolean: 
function(o) {
            
return typeof o === 'boolean';
        },

        isString: 
function(o) {
            
return typeof o === 'string';
        },
        
// infinity and NaN return false
        isNumber: function(o) {
            
return typeof o === 'number' && isFinite(o);
        },
        
// using {} or new Object();
        isPlainObject: function(o) {
            
// Make sure that DOM nodes and window objects don't pass
            return o && toString.call(o) === '[object Object]' && !o['nodeType'&& !o['setInterval'];
        },
            
        isEmptyObject: 
function(o) {
            
for (var p in o) {
                
return false;
            }
            
return true;
        },

        isFunction: 
function(o) {
            
// safari typeof NodeList 也返回function
            return toString.call(o) === '[object Function]';
        },

        isArray: 
function(o) {
            
return toString.call(o) === '[object Array]';
        },

        trim: trim 
? function(str) {
            
return (str === undefined) ? '' : trim.call(str);
        } : 
function(str) {
            
return (str === undefined) ? '' : str.toString().replace(REG_TRIM, '');
        },

        each: 
function(arr, fn, context) {
            
var l = (arr && arr.length) || 0, i = 0;
            
for (; i < l; ++i) {
                fn.call(context 
|| win, arr[i], i, arr);
            }
        },
        
        indexOf: indexOf 
?
                 
function(elem, arr) {
                    
return indexOf.call(arr, elem);
                 } :
                 
function(elem, arr) {
                    
for (var i = 0, len = arr.length; i < len; ++i) {
                        
if (arr[i] === elem) {
                            
return i;
                        } 
                    }
                    
return -1;
                 },

        inArray: 
function(elem, arr) {
            
return J.indexOf(elem, arr) !== -1;
        },

        makeArray: 
function(o) {
            
if (o === null || o === undefined) return [];
            
if (J.isArray(o)) return o;
            
            
if (typeof o.length !== 'number' || typeof o === 'string' || J.isFunction(o)) {
                
return [o];
            } 

            
// ie不支持 slice 转换 Nodelist, 降级到普通方法
            if (o.item && J.UA.ie) { //-------- 需要kissy-ua.js支持
                var ret = [], i = 0, len = o.length;
                
for (; i < len; ++i) {
                    ret[i] 
= o[i];
                }
                
return ret;
            } 

            
return AP.slice.call(o);
        },

        filter: filter 
?
                
function(arr, fn, context) {
                    
return filter.call(arr, fn, context);
                } :
                
function(arr, fn, context) {
                    
var ret = [];
                    J.each(arr, 
function(item, i, arr) {
                        
if (fn.call(context, item, i, arr)) {
                            ret.push(item);
                        }
                    });
                    
return ret;
                },


        
        param: 
function(o) {
            
if (!J.isPlainObject(o)) return '';
            
            
var buf = [], key, val;
            
for (key in o) {
                val 
= o[key];
                key 
= encode(key);
            

                
if (isValidParamValue(value)) {
                    buf.push(key, 
'=', encode(val + ''), '&');
                } 
                
else if (J.isArray(val) && val.length) {
                    
for (var i = 0, len = val.length; i < len; ++i) {
                        
if (isValidParamValue(val[i])) {
                            buf.push(key, 
'[]=', encode(val[i] + ''), '&');
                        } 
                    }
                } 
            }
            buf.pop(); 
// 弹出最后多余的&
            return buf.join('');
        },
        
        unparam: 
function(str, sep) {
            
if (typeof str !== 'string' || (str = J.trim(str)).length === 0return {};
            
            
var ret = {},
                pairs 
= str.split(sep || '&'),
                pair, key, val, m,
                i 
= 0, len = pairs.length;

            
for (; i < len; i++) {
                pair 
= pairs[i].split('=');
                key 
= decode(pair[0]);
            

                
// pair[1] 可能包含gbk编码中文, 而decodeURIComponent 仅能处理utf-8 编码中文
                try {
                    val 
= decode(pair[1]);
                } 
catch(e) {
                    val 
= pair[1|| '';
                }

                
if ((m = key.match(REG_ARR_KEY)) && m[1]) {
                    ret[m[
1]] = ret[m[1]] || [];
                    ret[m[
1]].push(val);
                } 
else {
                    ret[key] 
= val;
                }
            }
            
return ret;
        },

        later: 
function(fn, when, periodic, o, data) {
            when 
= when || 0;
            o 
= o || {};
            
var m = fn, d = J.makeArray(data), f, r;

            
if (typeof fn === 'string') {
                m 
= o[fn];
            } 

            
if (!m) {
                J.error(
'method undefined');
            } 

            f 
= function() {
                m.apply(o, d);
            };

            r 
= (periodic) ? setInterval(f, when) : setTimeout(f, when);

            
return {
                id: r,
                interval: periodic,
                cancel: 
function() {
                    
if (this.interval) {
                        clearInterval(r);
                    } 
else {
                        clearTimeout(r);
                    }
                }
            };
        },

        now: 
function() {
            
return new Date().getTime();
        },

        globalEval: 
function(data) {
            
if (data && REG_NOT_WHITE.test(data)) {
                
var head = doc.getElementsByTagName('head')[0|| doc,
                    script 
= doc.createElement('script');

                script.text 
= data;
                head.insertBefore(script, head.firstChild);
                head.removeChild(script);
            } 
        }
    });

    
function isValidParamValue(val) {
        
var t = typeof val;
        
return val === null || (t !== 'object' && t !== 'function');
    }

    
if (loc && loc.search && loc.search.indexOf('ks-debug'!== -1) {
        J.Config.debug 
= true;
    } 
 });

1.isBoolean, isString, isNumber, isArray, isFunction类型判断函数 

类型判断函数没啥可说基本类型可以用typeof 复制类型使用Object.prototype.toString.call()来监测.

注意:

(1).isNumber 如果是infinity或NaN应该返回false. 所以加了isFinite(o)来限制.

(2).isFunction由于在safari下typeof NodeList也返回function. 所以还是用toString.call来监测. 

2. isPlainObject函数

作用: 检测一个Object是否由{}或new Object()创建.此版本比较简单.不能够防止{'nodeType':true}的hack.复杂的可以参考jQuery

3.isEmptyObject函数

作用: 检测一个对象是否为空对象. 

4.trim函数

作用:去除字符串的作用空格.kissy用的是比较简洁的正则.有更快效率的trim.但为了简洁性.可以忽略ms的效率差. 

5.each函数

作用:循环遍历数组.并调用回调函数. arr[i], i ,arr依次为回调函数的参数. 

测试用例:

(function(J) {
    J.each([
'a''b''c''d'], function(item, index, arr) {
        J.log(item 
+ index); // a0, b1, c2, d3
    });
})(J1616);

 6.indexOf函数

作用:检测一个元素在一个数组中是否存在.如果存在返回索引值.如果不存在则返回-1. 

测试用例:

(function(J) {
    J.log(J.indexOf(
'a', ['b''a''c'])); // 1
    J.log(J.indexOf('a', ['b''c''d'])); // -1
})(J1616);

7.inArray函数

作用:检测一个元素是否在数组中存在.如果存在返回true.否则返回false.

测试用例:

(function(J) {
    J.log(J.inArray(
'a', ['a''b''c'])); // true
    J.log(J.inArray('a', ['b''c''d'])); // false
})(J1616);