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