.深复制浅复制

1>浅拷贝:复制引用,就是新生成的拷贝和原来的拷贝指向同一个实例对象,彼此之前操作会相互影响(就是将一个变量赋给另一个变量)

变量复制

var src = {
       name:"src"
   }
   //复制一份src对象的应用
   var target = src;
   target.name = "target";
   console.log(src.name);   

函数复制

    function shallowClone (source){
        if(!source || typeof source != 'object'){//0,null,undefine,空字符串,NaN是false
            throw new Error ('error');
        }
        var targetObj = source.constructor === Array ? [] : {};
        for(var keys in source) {
            if(source.hasOwnProperty(keys)){//hasOwnPrototype是让他浅复制的原因
                targetObj[keys] = source[keys];
            }
        }
        return targetObj;
}

Object.assign()

2>深拷贝复制实例,新生成的拷贝和原来的拷贝之间没有相互影响,将对象中的数组、子对象进行深度递归遍历,直到其不是引用类型位置的时候再进行复制,这样就不会相互影响了。

1.数组

Array的slice单层var arr1=arr.slice(0)

concat单层var arr1=arr.concat()

es6的扩展运算符...只能复制单层,不可实现深层复制

    var arr = [1,2,3,4,5]
    var [ ...arr2 ] = arr
    arr[2] = 5
    console.log(arr)
console.log(arr2)
es6的Object.assign()单层复制
var arr1=Object.assign([],arr);

jq的extend

扫描二维码关注公众号,回复: 2173570 查看本文章

2.对象

var target = JSON.parse(JSON.stringify(source));(可以多层)可以满足基本的深复制需求,但是对于正则表达式类型、函数类型等无法进行深复制(而且会直接丢失相应的值),同时如果对象中存在循环引用的情况也无法正确处理,不支持undefine当值为undefine时他会自动跳过结果中不显示这个值

扩展运算符...只能复制单层,不可实现深层复制

var obj={
	name:'shisha',
	sex:'woman',
	old:{
		age:'20',
		year:"1997"
	}
}
var {...obj1}=obj;
es6的Object.assign()单层复制
var obj1=Object.assign({},obj);

jQuery中的extend

3.深复制代码

function deepCopy(p, c) {
    var c = c || {};
    for (var i in p) {
      if (typeof p[i] === 'object') {
        c[i] = (p[i].constructor === Array) ? [] : {};
        deepCopy(p[i], c[i]);
      } else {
         c[i] = p[i];
      }
    }
    return c;
}
var obj={a:1,b:{c:2,d:4}}
var doctor=deepCopy(obj);
var doctor1=deepCopy(obj,{e:4})
console.log(doctor);//{a:1,b:{c:2,d:4}}
console.log(doctor1);//{e:4,a:1,b:{c:2,d:4}}

4.Object.assign()单层复制

Object.assign(target, ...sources)

函数参数为一个目标对象(该对象作为最终的返回值),源对象(此处可以为任意多个)。拷贝过程中将调用源对象的getter方法,并在目标对象上使用setter方法实现目标对象的拷贝。

var obj1={a:1};
var obj2={b:2};
var obj3={c:3};
var obj=Object.assign(obj1,obj2,obj3)
console.log(obj1);//{a:1,b:2,c:3}
console.log(obj2);//{b:2}
console.log(obj3);//{c:3}

属性覆盖

var obj1=Object.assign({a:{b:2}},{a:{b:3,c:4}},{a:{b:9}})//{a:{b:9}}

实现es5版本的Object.assign

实现步骤:

1.判断是否原生支持该函数,如果不存在的话创建一个立即执行函数,该函数将创建一个assign函数绑定到Object上。

2.判断参数是否正确(目的对象不能为空,我们可以直接设置{}传递进去,但必须设置该值)

3.使用Object在原有的对象基础上返回该对象,并保存为out

4.使用for…in循环遍历出所有的可枚举的自有对象。并复制给新的目标对象(hasOwnProperty返回非原型链上的属性)

if (typeof Object.assign != 'function') {
  (function () {
	Object.assign = function (target) {
	 'use strict';
	 if (target === undefined || target === null) {
	   throw new TypeError('Cannot convert undefined or null to object');
	 }
	 var output = Object(target);
	 for (var index = 1; index < arguments.length; index++) {
	   var source = arguments[index];
	   if (source !== undefined && source !== null) {
	     for (var nextKey in source) {
	       if (source.hasOwnProperty(nextKey)) {
	         output[nextKey] = source[nextKey];
	       }
	     }
	   }
	 }
	 return output;
	};})();}

5.jq的extend方法

1》extend(boolen,dest,src1,src2,src3...)

第一个参数boolean代表是否进行深度拷贝可以省略默认浅拷贝(true深拷贝)

函数参数为一个目标对象(该对象作为最终的返回值),源对象(此处可以为任意多个)。

后面的参数如果和前面的参数存在相同的名称,那么后面的会覆盖前面的参数值。

var obj1={a:1};
var obj2={b:2};
var obj=$.extend(obj1,obj2);
console.log(obj)//{a:1,b:2}
console.log(obj1)//{a:1,b:2}
console.log(obj2)//{b:2}
同样的问题:var obj1=$.extend({a:{b:2}},{a:{b:3,c:4}},{a:{b:9}});//{a:{b:9}}

2》省略dest将该src合并到调用extend方法的对象中去

$.extend(src)该方法就是将src合并到jquery的全局对象中去。

$.extend({
	hello:function(){
		alert("net")
	}
})
$.hello();

$.fn.extend(src)该方法将src合并到jquery的实例对象中去

var b=$.fn.extend({
	hello:function(){
		alert("net")
	}
})
b.hello();
xtend({
	hello:function(){
		alert("net")
	}
})
$.hello();

$.fn.extend(src)该方法将src合并到jquery的实例对象中去

var b=$.fn.extend({
	hello:function(){
		alert("net")
	}
})
b.hello();












猜你喜欢

转载自blog.csdn.net/qq_41047322/article/details/81059421