当前位置:网站首页>深拷贝真难
深拷贝真难
2022-07-05 13:47:00 【wade3po】
深拷贝浅拷贝的原理我是已经懂了,之前也有分享过。只是深拷贝浅拷贝的方法却从来没有真的去了解过。
想想之前的面试,问到深拷贝浅拷贝的时候,都是说一下原理,问到方法,张口就来JSON.parse和JSON.stringify,如果有函数的话就递归循环拷贝。却从来没有写过递归或者循环拷贝的函数。
今天写了一下深拷贝数据的函数,发现深拷贝其实好难好难,单单一个数据的深拷贝就让我觉得脑壳都受不了了,更别说一些大佬们还提到了原型链、dom、RegExp、函数、浏览器内置函数之类的是否拷贝或者说怎么处理,再加上兼容,以后出去再也不敢说能写出深拷贝函数了。
今天也不是写个什么好的深拷贝函数,单纯的写一下数据处理的深拷贝,虽然对于json对象的深拷贝JSON.parse和JSON.stringify是最简单的,只是让自己稍微见见世面。
先上一个递归深拷贝的函数:
function clone(data) {
var target = data;
if(isObject(data)){
target = {};
for(var i in data) {
target[i] = clone(data[i])
}
}
if(isArray(data)){
target = [];
for (let i = 0; i < data.length; i++) {
target[i] = clone(data[i])
}
}
return target;
}
function isObject(x){
return Object.prototype.toString.call(x) === '[object Object]';
}
function isArray(x){
return Object.prototype.toString.call(x) === '[object Array]';
}
很简单,判断传进来的参数是否是数组或者对象,这边对数组或者对象的判断比较严格,如果是就分别循环递归拷贝子对象。这只是对对象和数组的深拷贝。for in我们都知道会遍历出自身和原型链上可枚举的属性,有时候我们是不想拷贝这些的。所以这边兼容就要在for in里面加上data.hasOwnProperty的判断。
基本上递归的拷贝都能理解,但是如果一个数据层级太多,会出现爆栈:
Maximum call stack size exceeded
包括JSON.parse和JSON.stringify也会。
这时候就要循环深拷贝了,直接上代码:
function cloneLoop(x) {
let target = '';
if(isObject(x)){
target = {};
};
if(isArray(x)){
target = [];
}
const loopList = [
{
parent: target,
key: undefined,
data: x,
}
];
while(loopList.length) {
const node = loopList.pop();
const parent = node.parent;
const key = node.key;
const data = node.data;
let res = parent;
if(typeof key !== 'undefined'){
if(isObject(data)) {
res = parent[key] = {};
};
if(isArray(data)) {
res = parent[key] = [];
}
}
if(isObject(data)){
for(let k in data) {
initLoopList(data[k], k, res);
}
}
if(isArray(data)){
for (let i = 0; i < data.length; i++) {
initLoopList(data[i], i, res);
}
}
}
function initLoopList(val, key, res) {
if (isObject(val) || isArray(val)) {
loopList.push({
parent: res,
key: key,
data: val,
});
} else {
res[key] = val;
}
}
return target;
}
function isObject(val){
return Object.prototype.toString.call(val) === '[object Object]'
}
function isArray(val){
return Object.prototype.toString.call(val) === '[object Array]'
}
我自己都不知道要这么去注释这个函数,精华就是这两个引用:
res = parent[key] = {};
res = parent[key] = [];
就是对引用稍微绕了一点,可以自己理解一下。
深拷贝暂时只能是了解到这种程度了,当然,一般来说数据不会有这么深的层级。这只是最简单的对数组对象的拷贝,没有涉及函数、dom或者原型链这些,连数据的引用都没考虑进去,比如:
let a = {};
let b = {b:b, c:c};
这种情况还得考虑是否保留引用还是创建新的。
最后提个序列化和反序列化的概念,今天分享的其实就是针对可以序列化和发序列化的数据。百度百科上面对序列化的定义:
序列化是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
不同语言有不同的方法,百度百科上面Java的序列化是转成二进制,反序列化是将二进制转成对象。而JavaScript我理解的序列化就是对象转成字符串,发序列化把字符串转成对象。
边栏推荐
- Self built shooting range 2022
- 【云资源】云资源安全管理用什么软件好?为什么?
- [public class preview]: basis and practice of video quality evaluation
- Mmseg - Mutli view time series data inspection and visualization
- Aikesheng sqle audit tool successfully completed the evaluation of "SQL quality management platform grading ability" of the Academy of communications and communications
- Attack and defense world crypto WP
- Idea set method annotation and class annotation
- Integer ==比较会自动拆箱 该变量不能赋值为空
- When using Tencent cloud for the first time, you can only use webshell connection instead of SSH connection.
- Redis6 master-slave replication and clustering
猜你喜欢
ZABBIX monitoring
Ordering system based on wechat applet
What about data leakage? " Watson k'7 moves to eliminate security threats
The development of speech recognition app with uni app is simple and fast.
Idea remote debugging agent
Flutter 3.0更新后如何应用到小程序开发中
:: ffff:192.168.31.101 what address is it?
Aikesheng sqle audit tool successfully completed the evaluation of "SQL quality management platform grading ability" of the Academy of communications and communications
Intranet penetration tool NetApp
redis6事务和锁机制
随机推荐
私有地址有那些
jasypt配置文件加密|快速入门|实战
Can graduate students not learn English? As long as the score of postgraduate entrance examination English or CET-6 is high!
Require, require in PHP_ once、include、include_ Detailed explanation of the efficiency of repeated introduction of once class library
laravel-dompdf导出pdf,中文乱码问题解决
Usage, installation and use of TortoiseSVN
Could not set property ‘id‘ of ‘class XX‘ with value ‘XX‘ argument type mismatch 解决办法
Matlab paper chart standard format output (dry goods)
什么叫做信息安全?包含哪些内容?与网络安全有什么区别?
Don't know these four caching modes, dare you say you understand caching?
::ffff:192.168.31.101 是一个什么地址?
MySQL get time
Network security HSRP protocol
ELFK部署
运筹说 第68期|2022年最新影响因子正式发布 快看管科领域期刊的变化
记录一下在深度学习-一些bug处理
面试官灵魂拷问:为什么代码规范要求 SQL 语句不要过多的 join?
龙芯派2代烧写PMON和重装系统
Laravel framework operation error: no application encryption key has been specified
Log4j utilization correlation