文章出處

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8">
        <title></title>
    </head>

    <body>
    </body>
    <script type="text/javascript">
(function(){

function jQuery(){
    // 一個對象工廠,以后生成新對象不用new了,直接執行這個方法即可。
    return new jQuery.fn.init();
}

// jQuery的初始方法
jQuery.fn = jQuery.prototype = {
    init:function(){
        
    }
};

jQuery.prototype.init.prototype = jQuery.fn;
// 修正構造器指向
jQuery.prototype.constructor = jQuery;


// 擴展方法
// 這個方法外部用依賴jQuery.type和jQuery.isPlainObject方法。
// 內部第一次用不會用到jQuery.type和jQuery.isPlainObject。
// 1.只有一個參數,且類型是對象,則對jQuery或者jQuery實例進行擴展
// 2.第一個參數是bool值,則來確定是否深拷貝。
// 3.深拷貝是指 拷貝值和被拷貝值都是對象,則進一步遍歷復制,而不是直接覆蓋。
// 比如{a:{"1":1}},{a:{"2":2}},淺拷貝結果是{a:{"2":2}},深拷貝結果是{a:{"1":1,"2":2}}
// 4.拷貝時要進行循環引用判斷
// 5.對被拷貝值不是數組,不是普通對象,強行生成一個新的。
// 6.可以對多個參數進行合并
jQuery.extend = jQuery.fn.extend = function() {
    
    var options, name, src, copy, copyIsArray, clone,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length,
        deep = false;

    // 第一個參數是bool值,第二個參數是目標值,索引從第三個參數開始
    // 第一個參數bool為true表示深拷貝
    if ( typeof target === "boolean" ) {
        deep = target;
        target = arguments[1] || {};
        i = 2;
    }

    // target不是object,不是array,不是正則,不是日期,不是function,則目標值是一個空對象。
    // typeof object,array,正則,日期 == "object"
    // typeof這個判斷方法讓人很揪心吶
    // 確定被拷貝對象是個{}類型
    if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
        target = {};
    }
    
    // 確定被拷貝對象是個{}類型,自己寫的
    //    var targetType = jQuery.type(target);
    //    var targetType_arr = ["object","function","array","date","regexp"];
    //    if(targetType_arr.indexOf(targetType) == -1){
    //        target = {};
    //    }
    
    // 只有一個參數傳入,目標值是jQuery函數自己,或者jQuery對象。看誰調用了。
    if ( length === i ) {
        target = this;
        --i;
    }

    // 開始遍歷復制
    for ( ; i < length; i++ ) {
        // 不是null或undefined的參數才可以,要知道null == undefined是true
        if ( (options = arguments[ i ]) != null ) {
            
            for ( name in options ) {
                // 拿到老,新同個key對應的value值
                src = target[ name ];
                copy = options[ name ];

                // 防止循環引用
                // 當拷貝值是被拷貝的對象,跳出循環
                if ( target === copy ) {
                    continue;
                }

                // 深拷貝,拷貝值非undefined,是普通對象或者是數組
                if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)) ) ) {
                    if ( copyIsArray ) {
                        copyIsArray = false;
                        // 確定一下 被拷貝值也是個數組
                        clone = src && jQuery.isArray(src) ? src : [];

                    } else {
                        clone = src && jQuery.isPlainObject(src) ? src : {};
                    }

                    // 遞歸調用
                    target[ name ] = jQuery.extend( deep, clone, copy );

                // 只要不是undefined,就可以賦值
                } else if ( copy !== undefined ) {
                    target[ name ] = copy;
                }
            }
        }
    }

    // 返回被拷貝的對象
    return target;
};
        

// jQuery的類方法
jQuery.extend({
    type:function(obj){
        return Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
    },
    isArray :Array.isArray,
    isNumeric : function( obj ) {
        // 不是無窮,不是NaN就是數字
        return !isNaN( parseFloat(obj) ) && isFinite( obj );
    },
    isPlainObject:function(obj){
        //普通對象不是DOM節點 或者 不是window對象 或者 是'object'
        if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
            return false;
        }
        
        // 當然類似window.location這種對象也不是普通對象,因為它不是來自Object
        // 一切普通對象來自Object。而Object.prototype.isPrototypeOf存在
        if ( obj.constructor &&
                !Object.hasOwnProperty.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
            return false;
        }
                
        return true;
    },
    isEmptyObject: function( obj ) {
        var name;
        for ( name in obj ) {
            return false;
        }
        return true;
    },
    isFunction: function( obj ) {
        return jQuery.type(obj) === "function";
    },
    isWindow:function(obj){
        // window對象里面有window屬性
        return obj != null && obj === obj.window;
    }

});

// jQuery的實例方法
jQuery.fn.extend({
    css:function(){
        alert("css");
    }
});

// 模塊化和掛載
~function(){
    // CMD
    if ( typeof module === "object" && module && typeof module.exports === "object" ) {
        module.exports = jQuery;
    } else {
    // AMD
        if ( typeof define === "function" && define.amd ) {
            define( "jquery", [], function () { return jQuery; } );
        }
    }
    
    // 掛載全局變量
    if ( typeof window === "object" && typeof window.document === "object" ) {
        window.jQuery = window.$ = jQuery;
    }
}();



})();



        
        
        
        
        
        var arr = jQuery.extend({},{"c":[5,6]})
        console.log(arr);
        
        var a = jQuery.type(999);
        alert(a)
    </script>

</html>

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()