[转帖]Mootools源码分析-02 -- Utils

原帖地址:http://space.flash8.net/space/?uid-18713-action-viewspace-itemid-400118

原作者:我佛山人

 

 

//检查对象是否已经定义或者已经赋值
function $chk(obj)    {
    
return !!(obj || ōbj === 0);
};

//通用清除计时器的方法,即能清setTimeout,又能清setInterval,即使计时器不存在也不会报错
function $clear(timer)    {
    clearTimeout(timer);
    clearInterval(timer);
    
return null;
};

/*
检查对象属性是否已初始化/定义,注意只能检查对象的属性,不能直接检查变量
因为未定义变量在调用本方法前便会抛出错误,切记
*/
function $defined(obj)    {
    
return (obj != undefined);
};

//一个空的函数,主要用于事件的初始化
function $empty()    {};

//闭包应用,延后取指定的参数值
function $arguments(i)    {
    
return function()    {
        
return arguments[i];
    };
};

//lambda(匿名)函数,将指定变量函数化,保证返回一个function对象,类似$splat,将变量数组化
function $lambda(value)    {
    
return (typeof value == 'function'? value : function()    {
        
return value;
    };
};

//浅拷贝扩展,不考虑object型属性的,只是简单的覆盖
function $extend(original, extended)    {
    
for (var key in (extended || {}))    original[key] = extended[key];
    
return original;
};

//解链对象,主要是解决object类型的变量赋值时会影响原值的问题,所以修改其实我觉得叫clone的话更明了
function $unlink(object)    {
    
var unlinked = null;

    
switch ($type(object))    {
    
case 'object':
        unlinked 
= {};

        
//深拷贝
        for (var p in object)    unlinked[p] = $unlink(object[p]);
        
break;
    
case 'hash':

        
//深拷贝
        unlinked = $unlink(object.getClean());
        
break;
    
case 'array':
        unlinked 
= [];

        
//深拷贝
        for (var i = 0, l = object.length; i < l; i++)    unlinked[i] = $unlink(object[i]);
        
break;
    
default:
        
return object;
    }

    
return unlinked;
};

//合并所有对象,参数位置越后优先级越高,就是说后面的参数对象属性会覆盖前面的,注意用到了$unlink
function $merge()    {
    
var mix = {};
    
for (var i = 0, l = arguments.length; i < l; i++)    {
        
var ōbject = arguments[i];
        
if ($type(object) != 'object'continue;
        
for (var key in object)    {
            
var ōp = object[key], mp = mix[key];
            mix[key] 
= (mp && $type(op) == 'object' && $type(mp) == 'object'? $merge(mp, op) : $unlink(op);
        }
    }
    
return mix;
};

//返回参数列表中从左到右第一个已定义的表达式的值
function $pick()    {
    
for (var i = 0, l = arguments.length; i < l; i++)    {
        
if ($defined(arguments[i]))    return arguments[i];
    }
    
return null;
};

//在min到max之间取一个随机数
function $random(min, max)    {
    
return Math.floor(Math.random() * (max - min + 1+ min);
};

//变量数组化,通常用于保证之后的代码能执行数组的each方法
function $splat(obj)    {
    
var type = $type(obj);
    
return (type) ? ((type != 'array' && type != 'arguments'? [obj] : obj) : [];
};

//当前的时间截,Fx中的时间周期判断使用较多
var $time = Date.now || function()    {
    
return new Date().getTime();
};

//依次尝试执行参数列表中的函数,与Prototype的Try.these异工同曲之妙,只是更简练
function $try()    {
    
for (var i = 0, l = arguments.length; i < l; i++)    {
        
try {
            
return arguments[i]();
        } 
catch(e)    {}
    }
    
return null;
};

//判断对象类型,JS中很多类型typeof都是object,无法精确判断,但是因为有Native的实现,使精确判断类型成为了可能
function $type(obj)    {
    
if (obj == undefined)    return false;

    
//此行代码的实现有赖于Native的创意
    if (obj.$family)
        
return (obj.$family.name == 'number' && !isFinite(obj)) ? false : obj.$family.name;
    
if (obj.nodeName)    {
        
switch (obj.nodeType)    {
        
case 1return 'element';
        
case 3return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
        }
    } 
else if (typeof obj.length == 'number')    {
        
if (obj.callee) return 'arguments';
        
else if (obj.item) return 'collection';
    }
    
return typeof obj;
};

 

posted @ 2009-10-22 10:32  webgis松鼠  阅读(414)  评论(0编辑  收藏  举报