一、浅克隆:克隆一层
- 对象
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对象->空对象 日期对象->字符串 ...```javascriptlet 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;};
