一、浅克隆:克隆一层
- 对象
Object.assign({}, obj)
- 展开运算符
let new_obj = { ...obj };
- 循环赋值
let new_obj = {};
_.each(obj, (value, key) => { new_obj[key] = value; });
- 数组
arrayObject.slice(start,end)
:返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素- 展开运算符
...
concat()
Object.assign({}, array)
```javascript 一、把对象进行克隆 let new_obj = Object.assign({}, obj); let new_obj = { …obj };
let newobj = {}; .each(obj, (value, key) => { new_obj[key] = value; });
二、把数组进行克隆
// 1. slice let arr = [2,4,434,43] let arr1= arr.slice() arr[0] = ‘a’ console.log(arr,arr1) // [ 2, 4, 434, 43 ] console.log(arr1 === arr) // false
// 2. 简单遍历 Array.prototype.clone = function(){ let a=[]; for(let i=0,l=this.length;i<l;i++) { a.push(this[i]); } return a; } let arr = [‘aaa’,’bbb’,’ccc’,’wwwww’,’ddd’] let arr2 = arr.clone() console.log(arr2) console.log( arr2 === arr )
// 3. concat Array.prototype.clone=function(){ return [].concat(this); //或者 return this.concat(); } let arr = [‘aaa’,’asss’] let arr1 = arr.clone() arr[0] = 123 console.log(arr,arr1)
// 4. Object.assign () 浅复制,也可以实现数组的克隆 let arr = [‘sdsd’,123,123,123] let arr1 = [] Object.assign(arr1,arr) arr[1] = ‘aaaa’ console.log(arr,arr1) // [ ‘sdsd’, ‘aaaa’, 123, 123 ] [ ‘sdsd’, 123, 123, 123 ]
// 5. 扩展运算符 const a1 = [1, 2]; // 写法一 const a2 = […a1]; a1[0] = ‘aaa’ console.log(a1,a2)
<a name="p370s"></a>
## 深克隆
1. **实现深克隆最便捷办法**
1. `**JSON.stringify**`: 把对象/数组变为JSON字符串
1. `**JSON.parse**`: 把JSON字符串变为对象/数组「浏览器需要重新开辟所有内存」
1. 【弊端】
+ 不允许出现套娃操作<br /> + 属性值不能是BigInt会报错 Uncaught TypeError: Do not know how to serialize a BigInt<br /> + 丢失一些内容:只要属性值是 symbol/undefined/function 这些类型的<br /> + 还有信息不准确的,例如:正则->空对象 Error对象->空对象 日期对象->字符串 ...
```javascript
let obj = {
url: '/api/list',
method: 'GET',
cache: false,
timeout: 1000,
key: Symbol('KEY'),
big: 10n,
n: null,
u: undefined,
headers: {
'Content-Type': 'application/json',
post: {
'X-Token': 'xxx'
}
},
arr: [10, 20, 30],
reg: /^\d+$/,
time: new Date(),
fn: function () {
console.log(this);
},
err: new Error('xxx')
};
obj.obj = obj;
========实现深克隆最便捷办法
JSON.stringify:把对象/数组变为JSON字符串
JSON.parse:把JSON字符串变为对象/数组「浏览器会重新开辟所有内存」
【弊端】
+ 不允许出现套娃操作
+ 属性值不能是BigInt会报错 Uncaught TypeError: Do not know how to serialize a BigInt
+ 丢失一些内容:只要属性值是 symbol/undefined/function 这些类型的
+ 还有信息不准确的,例如:正则->空对象 Error对象->空对象 日期对象->字符串 ...
let newObj = JSON.parse(JSON.stringify(obj));
Qs.stringify:把对象变为urlencoded格式字符串 “xxx=xxx&xxx=xxx”
Qs.parse:把urlencoded格式字符串变为对象
【也存在很多问题】
console.log(Qs.parse(Qs.stringify(obj)));
// 实现数组和对象深/浅拷贝
var clone = function clone() {
var target = arguments[0],
deep = false,
type,
isArray,
isObject,
result,
Ctor,
treated = arguments[arguments.length - 1];
!Array.isArray(treated) || !treated.treated ? (treated = [], treated.treated = true) : null;
if (typeof target === "boolean") { // 深克隆
deep = target;
target = arguments[1];
}
// 防止死递归的处理
if (treated.indexOf(target) > -1) return target;
treated.push(target);
// 校验target类型
type = toType(target);
isArray = Array.isArray(target);
isObject = isPlainObject(target);
// 特殊值的拷贝
if (target == null) return target;
Ctor = target.constructor; // Ctor是target的构造函数
// 正则|日期
if (/^(regexp|date)$/i.test(type)) return new Ctor(target);
// 错误类型
if (/^(error)$/i.test(type)) return new Ctor(target.message);
// 函数|生成器函数 函数的克隆?
if (/^(function|generatorfunction)$/i.test(type)) {
// 包装一层函数
return function proxy() {
var args = Array.from(arguments); // 得到参数列表
return target.apply(this, args); // 执行原来的函数
};
}
// 不是数组/对象
if (!isArray && !isObject) return target;
// 如果是数组/对象,我们依次迭代赋值给新的数组/对象
result = new Ctor(); // 根据target类型来创建新的数组/对象
each(target, function (copy, name) {
if (deep) {
// 深拷贝
result[name] = clone(deep, copy, treated);
return;
}
// 浅拷贝
result[name] = copy;
});
return result;
};