JavaScript数组及非数组对象的深浅克隆详解原理

目录
  • 什么是浅克隆、深克隆
  • 1.对数组进行克隆
    • 1.1 浅克隆
    • 1.2 深克隆
  • 2.对非数组对象进行克隆
    • 2.1 浅克隆
    • 2.2 深克隆
  • 3.整合深克隆函数

什么是浅克隆、深克隆

浅克隆:直接将存储在栈中的值赋值给对应变量,如果是基本数据类型,则直接赋值对应的值,如果是引用类型,则赋值的是地址。
深克隆:将数据赋值给对应的变量,从而产生一个与源数据不相干的新数据(数据地址已变化)。即对象各个层级的属性。
JavaScript中基本数据类型使用符号“=”可以进行克隆,引用数据类型使用符号“=”只是改变了变量的指向,并没有进行真正的克隆操作。

1.对数组进行克隆

1.1 浅克隆

使用for循环进行浅克隆。

var arr1 = ['demo', 1, 2];
var arr2 = [];
// 数组的浅克隆
for (var i = 0; i < arr1.length; i++) {
    arr2[i] = arr1[i];
}
console.log(arr2);
console.log(arr1 == arr2);

输出结果:

Array(3)0: "demo"1: 12: 2length: 3[[Prototype]]: Array(0)
false

1.2 深克隆

使用递归进行深克隆。

function deepClone(o) {
	var result = [];
	for (var i = 0; i < o.length; i++) {
		result.push(deepClone(o[i]));
	}
	return result;
}

2.对非数组对象进行克隆

2.1 浅克隆

使用for循环进行浅克隆。

var obj1 = { a: 1, b: 2, c: 3, d: [4, 5, { e: 'demo' }] };
var obj2 = {};
// 对象的浅克隆
for (var i in obj1) {
    obj2[i] = obj1[i];
}
console.log(obj2);
console.log(obj1 == obj2);

输出结果:

{a: 1, b: 2, c: 3, d: Array(3)}
false

2.2 深克隆

使用递归进行深克隆。

function deepClone(o) {
	var result = {};
	for (var i in o) {
		result[i] = deepClone(o[i]);
	}
	return result;
}

3.整合深克隆函数

var obj1 = { a: 1, b: 2, c: 3, d: [4, 5, { e: 'demo' }] };
var arr1 = ['demo', 1, 2];
// 深克隆
function deepClone(o) {
    if (Array.isArray(o)) {
        // 是数组
        var result = [];
        for (var i = 0; i < o.length; i++) {
            result.push(deepClone(o[i]));
        }
    } else if (typeof o == 'object') {
        // 非数组,是对象
        var result = {};
        for (var i in o) {
            result[i] = deepClone(o[i]);
        }
    } else {
        // 基本类型值
        var result = o;
    }
    return result;
}
console.log(deepClone(arr1));
console.log(deepClone(obj1));

到此这篇关于JavaScript数组及非数组对象的深浅克隆详解原理的文章就介绍到这了,更多相关JavaScript 数组内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JavaScript 数组去重详解

    目录 1.数组去重 2.数组去重里面的对象去重 3.根据数组某个字段相同,修改另外字段值 总结 1.数组去重 /********************************************** ╚description: ╚作者: 麒麟社 ╚时间: 2021-09-13 22:26:21 ╚名称: V1.0.5 ***********************************************/ var obj = ['麒麟','社','CC','DD','麒麟','社'

  • 一篇文章带你详细了解JavaScript数组

    目录 一.数组的作用: 二.数组的定义: 1.通过构造函数创建数组 2.通过字面量的方式创建数组 三.数组元素 四.数组长度 五.数组索引(下标) 六.数组注意的问题 1.数组中存储的数据可以是不一样的 2.数组的长度是可以改变的 3.总之 七.遍历数组 1.正序遍历 2.倒序遍历 八.数组中常见的案例 1.求数组中所有元素的和 2.求数组的平均数 3.求数组的最大值和最小值 4.冒泡排序 总结 数组:是一组有序的数据 一.数组的作用: 可以一次性存储多个数据 二.数组的定义: 1.通过构造函数

  • Javascript数组去重的几种方法详解

    目录 数组去重 1 双层for循环(类似冒泡排序的双层循环写法) 2 循环和indexof.循环和includes 3 利用对象属性不能重复去重 4 ES6 Set 5 ES6 Array. prototype.filter() 6 ES6 Array. prototype.reduce() 总结 数组去重 1 双层for循环(类似冒泡排序的双层循环写法) var arr = [2,3,4,2,34,21,1,12,3,4,1] for(var i =0;i<arr.length;i++){ /

  • JavaScript数组常用方法实例讲解总结

    目录 数组常用方法 concat() 方法 join() 方法 pop() 方法 push() 方法 reverse() 方法 shift() 方法 slice() 方法 sort() 方法 splice() 方法 toSource() 方法 toString() 方法 toLocaleString() 方法 unshift() 方法 valueOf() 方法 导读:在实际开发中,前端工程师除了写页面布局及样式还要对后端返回的数据进行处理,返回的数据大多数是json格式,一般都是返回一个对象或者

  • JS数组中常用方法技巧学会进阶成为大佬

    目录 splice()方法 join()方法 reverse()方法 every()方法 reduce()方法 filter()方法 findIndex()方法 和find()方法 findIndex() find() forEach()方法 some()方法 indexOf()方法 sort ()方法 push()方法 pop()方法 unshift()方法 shift()方法 splice()方法 截取替换数组 第一个参数是起始位置,第二个是截取的个数,第三是替换的元素 ,返回值是截取的元素

  • JavaScript数组及非数组对象的深浅克隆详解原理

    目录 什么是浅克隆.深克隆 1.对数组进行克隆 1.1 浅克隆 1.2 深克隆 2.对非数组对象进行克隆 2.1 浅克隆 2.2 深克隆 3.整合深克隆函数 什么是浅克隆.深克隆 浅克隆:直接将存储在栈中的值赋值给对应变量,如果是基本数据类型,则直接赋值对应的值,如果是引用类型,则赋值的是地址. 深克隆:将数据赋值给对应的变量,从而产生一个与源数据不相干的新数据(数据地址已变化).即对象各个层级的属性. JavaScript中基本数据类型使用符号"="可以进行克隆,引用数据类型使用符号

  • Java中的数组复制(clone与arraycopy)代码详解

    JAVA数组的复制是引用传递,而并不是其他语言的值传递. 1.clone protectedObjectclone() throwsCloneNotSupportedException创建并返回此对象的一个副本."副本"的准确含义可能依赖于对象的类.这样做的目的是,对于任何对象x,表达式: x.clone()!=x为true,表达式: x.clone().getClass()==x.getClass()也为true,但这些并非必须要满足的要求.一般情况下: x.clone().equa

  • JavaScript中Number对象的toFixed() 方法详解

    定义和用法 toFixed() 方法可把 Number 四舍五入为指定小数位数的数字. 语法 NumberObject.toFixed(num) 参数 描述 num 必需.规定小数的位数,是 0 ~ 20 之间的值,包括 0 和 20,有些实现可以支持更大的数值范围.如果省略了该参数,将用 0 代替. 返回值 返回 NumberObject 的字符串表示,不采用指数计数法,小数点后有固定的 num 位数字.如果必要,该数字会被舍入,也可以用 0 补足,以便它达到指定的长度.如果 num 大于 l

  • C语言变长数组 struct中char data[0]的用法详解

    今天在看一段代码时出现了用结构体实现变长数组的写法,一开始因为忘记了这种技术,所以老觉得作者的源码有误,最后经过我深思之后,终于想起以前看过的用struct实现变长数组的技术.下面是我在网上找到的一篇讲解很清楚的文章. 在实际的编程中,我们经常需要使用变长数组,但是C语言并不支持变长的数组.此时,我们可以使用结构体的方法实现C语言变长数组. struct MyData { int nLen; char data[0];}; 在结构中,data是一个数组名:但该数组没有元素:该数组的真实地址紧随结

  • Go语言实现二维数组的2种遍历方式以及案例详解

    二维数组遍历的2种方式: package main import ( "fmt" ) func main() { //定义一个二维数组 var arr = [2][3]int{{1, 4, 3},{7, 5, 6}} //方式1. 用for循环来遍历 for i := 0; i < len(arr); i++ { for j := 0; j < len(arr[i]); j++ { fmt.Printf("%v ",arr[i][j]) } fmt.Pr

  • Java队列篇之实现数组模拟队列及可复用环形队列详解

    队列简介 队列是一个有序列表,可以用数组或是链表来实现. 遵循先入先出的原则.即先存入队列的数据,先取出,后存入的后取出. 示意图:(使用数组模拟队列示意图) 有两个分别指向头部和尾部的"指针". 数组模拟队列(无法复用) 1.实现思路 队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如下图,其中maxSize是该队列的最大容量. 因为队列的输出.输入是分别从前后端来处理,因此需要两个变量front及rear分别记录队列前后端的下标,front会随着数据输出而改变

  • Java对象Serializable接口实现详解

    这篇文章主要介绍了Java对象Serializable接口实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 导读 最近这段时间一直在忙着编写Java业务代码,麻木地搬着Ctrl-C.Ctrl-V的砖,在不知道重复了多少次定义Java实体对象时"implements Serializable"的C/V大法后,脑海中突然冒出一个思维(A):问了自己一句"Java实体对象为什么一定要实现Serializable接口呢?&qu

  • JavaScript动画实例之粒子文本的实现方法详解

    1.粒子文本的实现原理 粒子文本的实现原理是:使用两张 canvas,一张是用户看不到的canvas1,用来绘制文本:另一张是用户看到的canvas2,用来根据canvas1中绘制的文本数据来生成粒子. 先在canvas1中用如下的语句绘制待显示的文本. ctx1.font = '100px PingFang SC'; ctx1.textAlign = 'center'; ctx1.baseline = 'middle'; ctx1.fillText('Happy New Year',canva

  • nodejs 全局变量和全局对象知识点及用法详解

    1.全局对象 所有模块都可以调用 1)global:表示Node所在的全局环境,类似于浏览器中的window对象. 2)process:指向Node内置的process模块,允许开发者与当前进程互动. 例如你在DOS或终端窗口直接输入node,就会进入NODE的命令行方式(REPL环境).退出要退出的话,可以输入 process.exit(); 3)console:指向Node内置的console模块,提供命令行环境中的标准输入.标准输出功能. 通常是写console.log(),无须多言 2.

  • JavaScript箭头函数与普通函数的区别示例详解

    目录 箭头函数与普通函数的区别 箭头函数的理解 箭头函数里的this指向 总结 箭头函数与普通函数的区别 要讨论箭头函数和普通函数的区别,首先来看看两者的基本格式 普通函数和箭头共同点就是圆括号和大括号,圆括号里面一般放置参数,大括号一般放置函数主体,很明显箭头函数不需要写那么长,举个例子,有一个数组,使用map方法为数组的每个元素增加字符 let arr=['昨天','今天','明天'] let newarr=arr.map(function(item){ return item+='放假'

随机推荐