$(selector)須要返回一個利用selector初始化的實例,而且這個實例可以訪問jquery的原型方法,而且不使用new操做符。html
實現這兩步,須要:jquery
咱們能夠這樣作:git
var $ = function(selector,context){ *return new init(); } $.prototype = { foo:function(); bar:xxx; } function init(){ ...; } *init.prototype = $.prototype var something = $(selector);
可是在jquery中,init函數是在$.prototype內部的,所以帶星號的語句須要修改成:github
return new $.prototype.init(); $.prototype.init.prototype = $.prototype;
jquery的源碼則是數組
return new jQuery.fn.init( selector, context, rootjQuery );//fn爲jquery.prototype的一個引用。
在全部的方法最後添加return this便可實現鏈式調用。函數
extent函數源碼分析oop
jQuery.extend = jQuery.fn.extend = function() { var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {}, // 常見用法 jQuery.extend( obj1, obj2 ),此時,target爲arguments[0] i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { // 若是第一個參數爲true,即 jQuery.extend( true, obj1, obj2 ); 的狀況 deep = target; // 此時target是true target = arguments[1] || {}; // target改成 obj1 // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !jQuery.isFunction(target) ) { // 處理奇怪的狀況,好比 jQuery.extend( 'hello' , {nick: 'casper})~~ target = {}; } // extend jQuery itself if only one argument is passed if ( length === i ) { // 處理這種狀況 jQuery.extend(obj),或 jQuery.fn.extend( obj ) target = this; // jQuery.extend時,this指的是jQuery;jQuery.fn.extend時,this指的是jQuery.fn --i; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) { // 好比 jQuery.extend( obj1, obj2, obj3, ojb4 ),options則爲 obj二、obj3... // Extend the base object for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { // 防止自引用,不贅述 continue; } // Recurse if we're merging plain objects or arrays // 若是是深拷貝,且被拷貝的屬性值自己是個對象 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { if ( copyIsArray ) { // 被拷貝的屬性值是個數組 copyIsArray = false; clone = src && jQuery.isArray(src) ? src : []; } else { 被拷貝的屬性值是個plainObject,好比{ nick: 'casper' } clone = src && jQuery.isPlainObject(src) ? src : {}; } // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); // 遞歸~ // Don't bring in undefined values } else if ( copy !== undefined ) { // 淺拷貝,且屬性值不爲undefined target[ name ] = copy; } } } } // Return the modified object return target; }
extent函數源碼分析引用自:http://www.cnblogs.com/aaronjs/p/3278578.html源碼分析
深複製須要遵照的規則:(假設將obj2中的屬性深複製至obj1中)this
實現:https://github.com/kangkang1234/deepCopy/blob/master/deepCopy.jsspa
function deepCopy(){ var len = arguments.length; if(len===1){ return arguments[0]; }else if(len===0){ return undefined; } var j=0; for(;j<len;j++){ if(!(arguments[j] instanceof Array)&&!(arguments[j] instanceof Object)){ throw new TypeError("arguments must be object or array."); } } var src,copy,option,copyIsArr; var target = arguments[0] || {}; var i = 1; for(;i<len;i++){ option = arguments[i]; for(name in option){ src = target[name]; copy = option[name]; if(copy&&((copyIsArr=copy instanceof Array)||(copy instanceof Object))){ //若是copy存在而且是數組或者對象 if(copyIsArr){ //若是copy是數組 src = (src&&src instanceof Array)?src:[]; //判斷target中是否有相同屬性名的屬性,而且該屬性爲數組。 target[name] = deepCopy(src,copy); }else{ src = src?src:{}; target[name] = deepCopy(src,copy); } } else { target[name] = copy; } } } return target; }