extend是jQuery中一個比較核心的代碼,若是有查看jQuery的源碼的話,就會發現jQuery在多處調用了extend方法。jquery
jQuery.prototype.extend = jQuery.extend = function(){ var target = arguments[0] || {}; //獲取第一個參數做爲目標結果 var i = 1; //設置開始擴展的下標,擴展時第一個參數不會進行改變,不須要遍歷 var length = arguments.length; var option; if(typeof target !== 'object') { target = {}; } for(; i< length; i++){ option = arguments[i] for(var name in option){ target[name] = option[name] } } return target } //調用 var i = {a: 0}; var b = {c: 9}; console.log($().extend(i,b)) // {a:0, c:9}
在上面,咱們已經寫出的extend的基礎版本,可是若是咱們簡單測試一下,就會發現還是有問題存在的。
咱們可使用上面的方法,對下面的對象進行擴展函數
var n = { al: 90, m: { d: 23, } } var b = {m:{ c: 98 }}; console.log($().extend(n,b)) // {al: 90, m: { c: 98 }}
簡單的從結果來看,返回的結果並不符合咱們的預期,基礎版本的方法彷佛只是簡單的值替換而已。那麼來簡單升級一下代碼吧。
在升級代碼以前,須要瞭解一下關於淺拷貝和深拷貝的相關。測試
var i = {a: 0}; var b = {c: 9}; console.log($().extend(i,b)) // {a: 90, c:9} i.a = 90
var n = { al: 90, m: { d: 23, } } var b = {m:{ c: 98 }}; console.log($().extend(true,{},n,b)) console.log(n) n.al = "cs"
結果:
this
jQuery.extend是提供深拷貝的,須要將第一參數傳爲true。
基本思路:prototype
var deep = false; if (typeof target === 'boolean') { deep = target; target = arguments[1]; i = 2; //由於第一參數爲boolean,因此拷貝對象從argument[1]開始,但一般第一個拷貝對象是不須要比遍歷的,因此遍歷下標從2開始。 }
if (length === i) { //此時extend參數只有一個,可是目標應該是this,因此獲取到this; target = this; //但同時 i = 1;沒法進行遍歷,因此將遍歷下標後退一位 i--; } jQuery.extend({ isArray: function(obj) { return toString.call(obj) === '[object Array]'; }, isPainObj: function(obj) { return toString.call(obj) === '[object Object]'; } })
jQuery.prototype.extend = jQuery.extend = function(){ var target = arguments[0] || {}; var i = 1; var length = arguments.length; var option, copy, src, copyisArray, clone; for(; i< length; i++){ if((option = arguments[i]) != null ){ for(name in option) { src = target[name]; copy = option[name]; if(jQuery.isPainObj(copy) || (copyisArray = jQuery.isArray(copy))) { if(copyisArray) { copyisArray = false; clone = src && jQuery.isArray(src) ? src : []; } else { clone = src && jQuery.isPainObj(src) ? src : {}; } target[name] = jQuery.extend(clone,copy) } else if(copy !== undefined) { target[name] = copy } } } } return target }
行了,到這裏爲止,咱們就已經完成了簡單的extend函數了,其實比較重要的是深拷貝和淺拷貝,關於這一點,下次再記錄吧。code