js深拷贝的三种实现方式(使用json实现深克隆)
其实js深拷贝的三种实现方式的问题并不复杂,但是又很多的朋友都不太了解使用json实现深克隆,因此呢,今天小编就来为大家分享js深拷贝的三种实现方式的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!
深拷贝的三种实现方式
深拷贝的三种实现方式如下:
1、使用递归的方式实现深拷贝
//使用递归的方式实现数组、对象的深拷贝functiondeepClone1(obj){
//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
varobjClone=Array、isArray(obj)?[]:{};
//进行深拷贝的不能为空,并且是对象或者是
if(obj&&typeofobj==="object"){
for(keyinobj){
if(obj、hasOwnProperty(key)){
if(obj[key]&&typeofobj[key]==="object"){
objClone[key]=deepClone1(obj[key]);
2、通过JSON对象实现深拷贝
//通过js的内置对象JSON来进行数组对象的深拷贝
functiondeepClone2(obj){
var_obj=JSON、stringify(obj),
objClone=JSON、parse(_obj);
returnobjClone;
}JSON对象实现深拷贝的一些问题
3、通过jQuery的extend方法实现深拷贝
vararray=[1,2,3,4];
varnewArray=$、extend(true,[],array);
构造函数
在C++面向对象程序设计中,通过构造函数对对象进行初始化,它可以为对象在计算机内存中开辟内存空间,也可以为对象的数据成员提供初始值。构造函数是一个与类同名,没有返回值的特殊成员函数,每当创建一个对象时(包括使用new动态创建对象),编译系统就会自动调用构造函数。
构造函数象类以外的一般函数和类成员函数一样可以重载和带缺省参数,构造函数的重载为对象的生成提供了各种灵活的手段。
构造函数分为缺省构造函数(默认构造函数)和用户自定义构造函数。当程序员没有定义构造函数时,系统会提供一个无参的缺省构造函数。如果用户自定义了一个构造函数,编译器提供的缺省构造函数就自动消失了。
JS中实现深拷贝的几种方法(object,Array)
4.通过第三方工具实现深拷贝
lodash.cloneDeep
数组深拷贝
1. concat(arr1, arr2,....)
2. slice(idx1, idx2)
参数可以省略
1)没有参数是拷贝数组
2)只有一个参数是从该位置起到结束拷贝数组元素
3)两个参数,拷贝从起始位置到结束位置的元素(不包含结束位置的元素:含头不含尾)
注意:当数组中的元素均为一维是深拷贝
数组中元素一维以上是值的引用
js深拷贝和浅拷贝的区别
1.浅拷贝:复制一份引用,所有引用对象都指向一份数据,并且都可以修改这份数据。
2.深拷贝(复杂):复制变量值,对于非基本类型的变量,则递归至基本类型变量后,再复制。
一、数组的深浅拷贝
在使用JavaScript对数组进行操作的时候,我们经常需要将数组进行备份,事实证明如果只是简单的将它赋予其他变量,那么我们只要更改其中的任何一个,然后其他的也会跟着改变,这就导致了问题的发生。
var arr= ["One","Two","Three"]; var arrto= arr; arrto[1]="test"; document.writeln("数组的原始值:"+ arr+"<br/>");//Export:数组的原始值:One,test,Three document.writeln("数组的新值:"+ arrto+"<br/>");//Export:数组的新值:One,test,Three
像上面的这种直接赋值的方式就是浅拷贝,很多时候,这样并不是我们想要得到的结果,其实我们想要的是arr的值不变,不是吗?
方法一:js的slice函数
var arr= ["One","Two","Three"]; var arrtoo= arr.slice(0); arrtoo[1]="set Map"; document.writeln("数组的原始值:"+ arr+"<br/>");//Export:数组的原始值:One,Two,Three document.writeln("数组的新值:"+ arrtoo+"<br/>");//Export:数组的新值:One,set Map,Three
方法二:js的concat方法
var arr= ["One","Two","Three"]; var arrtooo= arr.concat(); arrtooo[1]="set Map To"; document.writeln("数组的原始值:"+ arr+"<br/>");//Export:数组的原始值:One,Two,Three document.writeln("数组的新值:"+ arrtooo+"<br/>");//Export:数组的新值:One,set Map To,Three
二、对象的深浅拷贝
var a={name:'yy',age:26}; var b=new Object(); b.name=a.name; b.age=a.age; a.name='xx'; console.log(b);//Object{ name="yy", age=26} console.log(a);//Object{ name="xx", age=26}
就是把对象的属性遍历一遍,赋给一个新的对象。
var deepCopy= function(source){ var result={}; for(var key in source){ result[key]= typeof source[key]==='object'? deepCoyp(source[key]): source[key];} return result;}
举一个jQuery中的例子:
jQuery.extend= jQuery.fn.extend= function(){//1.将extend方法扩展到JQ(函数)下边:扩展静态方法//2. jQuery.fn.extend把extend扩展到jq.fn下且jQuery.fn= jQuery.prototype扩展实例方法// 1.2.功能相似 var options, name, src, copy, copyIsArray, clone,//定义一些变量 target= arguments[0]||{},//目标元素是【0】第一个元素$.extend( a,{ name:'hello'},{ age: 30}); i= 1,//第一个元素的位置 length= arguments.length,//第一个个对象的元素 deep= false;//是否是深拷贝默认 false不是// Handle a deep copy situation看是不是深拷贝情况 if( typeof target==="boolean"){//是布尔值 deep= target; target= arguments[1]||{};//目标元素是第二个$.extend( true, a, b)// 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)){//当目标不是对象或者不是函数的时候 target={};//变成一个空的jason}// extend jQuery itself if only one argument is passed看是不是插件情况 if( length=== i){//只写了一个对象要把这个对象扩展到jq源码上静态方法或者是实例方法 target= this;//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;//跳出本次循环继续执行//$.extend( a,{ name: a}));循环引用 a也是一个对象}// Recurse if we're merging plain objects or arrays深拷贝 if( deep&& copy&&( jQuery.isPlainObject(copy)||(copyIsArray= jQuery.isArray(copy)))){//是深拷贝且需有var b={ name:{ age: 30}};且b必须是对象自变量(jason)或者是个数组//递归 if( copyIsArray){//数组 copyIsArray= false; clone= src&& jQuery.isArray(src)? src: [];//定义一个空数组} else{//jason clone= src&& jQuery.isPlainObject(src)? src:{};//看原有的属性有没有且是不是jason定义一个空jason}// var a={ name:{ job:'it'}};看有没有原有的属性有的话在原有的上边添加// var b={ name:{age: 30}};//$.extend( true, a, b);//a继承b// console.log( a); a{ name:{ job:'it',age: 30}}如果只有一个{}则只有,age: 30// Never move original objects, clone(a) them 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;};
js深拷贝的三种实现方式的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于使用json实现深克隆、js深拷贝的三种实现方式的信息别忘了在本站进行查找哦。