QUnit源码阅读(1):工具函数

来源:互联网 发布:阿里云系统格机 编辑:程序博客网 时间:2024/05/17 01:07

QUnit 是 JavaScript单元测试框架。更加具体的介绍ref: http://qunitjs.com/

下面是QUnit中的一段代码:

(function() {    function F() {}    F.prototype = QUnit;    QUnit = new F();    // Make F QUnit's constructor so that we can add to the prototype later    QUnit.constructor = F;}());

What does it mean? I don't know. 直接把代码copy进浏览器中进行测试,同时定义

QUnit = {            add:function(a, b){return a+b;},            id: 1        };

调试后发现:

 

根据元素id取得元素function id( name ) {    return !!( typeof document !== "undefined" && document && document.getElementById ) &&        document.getElementById( name );}

!!感叹号的作用是什么??很显然不同于C/C++中的连续两次!。

他相当于三元运算符,返回boolean值。

var ret = !!document.getElementById

Equals to the following:

var ret = document.getElementById ? true : false;

Other practical techniques:

var num = 100;num = num +""; //var1+"" 转为 stringdocument.write(typeof num+" : "+num+"<br/>");            num = ~~num; //~~var1 转为 intdocument.write(typeof num+" : "+num+"<br/>");            num = [num]//[var1] 转为 arraydocument.write(typeof num+" : "+"num instanceof Array"+(num instanceof Array)+" "+num+"<br/>");
//为元素elem增加类型为type的事件,对应的函数为fn//兼容Firefox,chrome及IE事件function addEvent( elem, type, fn ) {    if ( elem.addEventListener ) {        elem.addEventListener( type, fn, false );    } else if ( elem.attachEvent ) {        elem.attachEvent( "on" + type, fn );    } else {        fn();    }}
//把对象b中的属性和方法导出到对象a中function extend( a, b ) {    for ( var prop in b ) {        if ( b[ prop ] === undefined ) {            delete a[ prop ];        // Avoid "Member not found" error in IE8 caused by setting window.constructor        } else if ( prop !== "constructor" || a !== window ) {            a[ prop ] = b[ prop ];        }    }    return a;}
//异常栈中取得自己想要的信息// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)// Later Safari and IE10 are supposed to support error.stack as well// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stackfunction extractStacktrace( e, offset ) {    offset = offset === undefined ? 3 : offset;    var stack, include, i, regex;    if ( e.stacktrace ) {        // Opera        return e.stacktrace.split( "\n" )[ offset + 3 ];    } else if ( e.stack ) {        // Firefox, Chrome        stack = e.stack.split( "\n" );        if (/^error$/i.test( stack[0] ) ) {            stack.shift();        }        if ( fileName ) {            include = [];            for ( i = offset; i < stack.length; i++ ) {                if ( stack[ i ].indexOf( fileName ) != -1 ) {                    break;                }                include.push( stack[ i ] );            }            if ( include.length ) {                return include.join( "\n" );            }        }        return stack[ offset ];    } else if ( e.sourceURL ) {        // Safari, PhantomJS        // hopefully one day Safari provides actual stacktraces        // exclude useless self-reference for generated Error objects        if ( /qunit.js$/.test( e.sourceURL ) ) {            return;        }        // for actual exceptions, this is useful        return e.sourceURL + ":" + e.line;    }}function sourceFromStacktrace( offset ) {    try {        throw new Error();    } catch ( e ) {        return extractStacktrace( e, offset );    }}
好的类型检查实现  // Safe object type checking    is: function( type, obj ) {        return QUnit.objectType( obj ) == type;    },    objectType: function( obj ) {        if ( typeof obj === "undefined" ) {                return "undefined";        // consider: typeof null === object        }        if ( obj === null ) {                return "null";        }        var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || "";        switch ( type ) {            case "Number":                if ( isNaN(obj) ) {                    return "nan";                }                return "number";            case "String":            case "Boolean":            case "Array":            case "Date":            case "RegExp":            case "Function":                return type.toLowerCase();        }        if ( typeof obj === "object" ) {            return "object";        }        return undefined;    },
 在某一元素上触发事件// Trigger an event on an element.    // @example triggerEvent( document.body, "click" );    triggerEvent: function( elem, type, event ) {        if ( document.createEvent ) {            event = document.createEvent( "MouseEvents" );            event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,                0, 0, 0, 0, 0, false, false, false, false, 0, null);            elem.dispatchEvent( event );        } else if ( elem.fireEvent ) {            elem.fireEvent( "on" + type );        }    },
判断是否在数组中存在某一元素function inArray( elem, array ) {    if ( array.indexOf ) {        return array.indexOf( elem );    }    for ( var i = 0, length = array.length; i < length; i++ ) {        if ( array[ i ] === elem ) {            return i;        }    }    return -1;}
从元素中递归取得所有文本function getText( elems ) {    var i, elem,        ret = "";    for ( i = 0; elems[i]; i++ ) {        elem = elems[i];        // Get the text from text nodes and CDATA nodes        if ( elem.nodeType === 3 || elem.nodeType === 4 ) {            ret += elem.nodeValue;        // Traverse everything else, except comment nodes        } else if ( elem.nodeType !== 8 ) {            ret += getText( elem.childNodes );        }    }    return ret;}
0 0