$.extend() 深复制与浅复制深刻理解

  js 中分为基本变量,和引用变量。在$.extend(),体现得非常深刻。
  除了数组,对象,其他的变量都可以称为基本变量。

  var a = 3;
  var b = a;
   b = 4;
console.log(a);  //3
console.log(b);  //4
var a = {name:"strong"}
var b = a;
b.name = "Lee";
console.log(a.name) //  Lee;
console.log(b.name) //Lee;

ps:可见,b属性的变化,影响到了a , 这种赋值就是浅复制,而取消这种影响,就是深复制 ;


在jQuery源码中,对于 对象  还有一个判断函数 是 $.isPlainObject(),用于判断此对象是否为“纯对象”,纯对象就是变量直接申请的对象。

var  a = {
a:3
};
function cons(){
   this.a = 3;
}
var b = new cons();
// a就是纯对象,而b就不是。
以下为jquery中 isPlainObject 的源码。
//此函数的核心,就是以object.prototype.constructor 属性,来判断是否为纯对象。
//当 constructor是 Object() 时,为纯对象;当为其他构造函数时就是非纯函数。
isPlainObject: function( obj ) { var proto, Ctor; // Detect obvious negatives // Use toString instead of jQuery.type to catch host objects if ( !obj || toString.call( obj ) !== "[object Object]" ) { return false; } proto = getProto( obj ); //obj的原型 // Objects with no prototype (e.g., `Object.create( null )`) are plain if ( !proto ) { return true; } // Objects with prototype are plain if they were constructed by a global Object function Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; }


    ###深层复制的基本原理就是将对象引用,变为基本变量赋值,这样就不会出现对象引用后,修改对象属性,造成原对象属性污染。通俗一点,就是要把对象的属性(此属性为基本变量) 赋值给 另一个对象的相应属性;



所以我们可以自己先写一个较为简单的  深层复制 对象扩展函数,

function extend(target,src){ for( i in src){ var a = target[i]?target[i]:{};
//判断纯对象,并递归或直接赋值; target[i] = $.isPlainObject(src[i])?extend(a,src[i]):src[i]; } return target; }


ps:jquery中的深层复制只能对于纯对象,以下特例不会进行深层复制的

function a(){

this.a = 3;

}

var b = {

c :3,

d : new a()

}

var e = {};

$.extend(e,b);

b当中的d属性并不会深层复制给e,当e改变d属性时会影响b.d 的值;

以下为jquery中extend的源码:

jQuery.extend = jQuery.fn.extend = function() { //arguments[0] -> boolean; //arguments[1] -> target; //arguments[2] -> src var options, name, src, copy, copyIsArray, clone, target = arguments[ 0 ] || {}, i = 1, //记录处理的参数位置 length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; // Skip the boolean and the target target = arguments[ i ] || {}; i++; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { target = {}; } // Extend jQuery itself if only one argument is passed //like $().extend({a:3}) //另外一种形式$.extend(a,b) //jquery工具方法; if ( i === length ) { target = this; i--; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( ( options = arguments[ i ] ) != null ) { // 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 //recurse 递归吧 if ( deep && copy && ( jQuery.isPlainObject( copy ) || ( copyIsArray = jQuery.isArray( copy ) ) ) ) { if ( copyIsArray ) { // 此if,根据src 类型 , 改变clone; copyIsArray = false; clone = src && jQuery.isArray( src ) ? src : []; } else { clone = src && jQuery.isPlainObject( src ) ? src : {}; } // Never move original objects, clone them //copy 是对象,且好几层对象,递归复制,保障深层复制成功。 target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; };


           



























































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值