多是最全的js对象克隆和数组克隆方法

引子:表单数据的克隆

工做中咱们须要用到对象或者数组的复制功能es6

  • 提交的form表单,须要进行处理,例如将表单中的数组变成','链接的字符串,这个时候咱们直接对原表单直接处理是不稳当的

那么问题来了,我该用什么方法去克隆这个含有数组的表单呢?数组

深克隆和浅克隆的区别

在解决上述问题以前,咱们应该明确一点什么是深克隆,什么是浅克隆?函数

浅克隆是把一个对象里面的数据复制一份出来,当对象中含有对象或者数组这种引用类型的数据时,浅克隆也只是复制其引用地址,所以修改新复制的对象中引用类型的数据时,原对象也是会改变的,所以浅克隆适用于对象或数组中只有简单数据类型时使用code

对于上面的表单数据的克隆来讲,此时咱们应该采用的是深克隆的方式,由于咱们并不想让原表单对象随咱们新复制出对象的改变而改变orm

Array&Object通用深克隆方法

着急的兄弟姐妹能够不用看下面,直接copy下面的通用方法,想多了解的,欢迎继续看下去对象

1、最简单粗暴的方法,缺点是不能复制函数

let new = JSON.parse(JSON.stringify(target))

2、经过递归方式的方法,解决了不能复制函数的问题(最全面的深克隆方法)

function deepClone(obj) {
  var o, i, j, k;
  if (typeof (obj) != "object" || obj === null) return obj;
  if (obj instanceof(Array)) {
    o = [];
    i = 0;
    j = obj.length;
    for (; i < j; i++) {
      if (typeof (obj[i]) == "object" && obj[i] != null) {
        o[i] = arguments.callee(obj[i]);
      } else {
        o[i] = obj[i];
      }
    }
  } else {
    o = {};
    for (i in obj) {
      if (typeof (obj[i]) == "object" && obj[i] != null) {
        o[i] = arguments.callee(obj[i]);
      } else {
        o[i] = obj[i];
      }
    }
  }
  return o;
}

Object克隆

1、浅克隆

  1. Object.assign({}, targetObj) 查看Object.assgin的介绍
    let targetObj = {
    	  a: [1, 2],
    	  b: 2
    	}
    	let obj = Object.assign({}, targetObj)
    	targetObj.a[0] = 0
    	console.log(obj)
  2. 遍历目标对象的属性,赋给新的对象
    let targetObj = {
    	  a: [1, 2],
    	  b: 2
    	}
    	let obj = {}
    	for (var k in targetObj) {
    	  obj[k] = targetObj[k]
    	}
    	targetObj.a[0] = 0
    	console.log(obj)
    经过上面的代码可知,此方法也是浅克隆
  3. es6的扩展运算符...
    let targetObj = {
    	  a: [1, 2],
    	  b: 2,
    	  c: function () {
    		consle.log(333)
    	  }
    	}
    	let obj = {...targetObj}
    	targetObj.a[0] = 0
    	console.log(obj, targetObj)

2、深克隆

  1. JSON.parse递归

    把对象序列化再解析回来,对象中有函数function则不能正确复制ip

    let targetObj = {
    	  a: [1, 2],
    	  b: 2,
    	  c: function () {
    		consle.log(333)
    	  }
    	}
    	let obj = {}
    	obj = JSON.parse(JSON.stringify(targetObj))
    	targetObj.a[0] = 0
    	console.log(obj)

    经过上面代码结果可知,目标对象的改变不会影响到新对象的值,然而属性c并无复制过来字符串

Array克隆

1、浅克隆

  1. 数组遍历赋值
    let targetArr = [1, {a: 1, b:2}, 3]
    	let arr = []
    	for (var i = 0, len = targetArr.length; i < len; i++) {
    	  arr[i] = targetArr[i]
    	}
    	targetArr[1].a = 0
    	console.log(arr, targetArr)
  2. concat
    let targetArr = [1, {a: 1, b:2}, 3]
    	let arr = targetArr.concat()
    	targetArr[1].a = 0
    	console.log(arr, targetArr)
  3. es6扩展运算符...
    let targetArr = [1, {a: 1, b:2}, 3]
    	let arr = [...targetArr]
    	targetArr[1].a = 0
    	console.log(arr, targetArr)
  4. slice
    let targetArr = [1, {a: 1, b:2}, 3]
    	let arr = targetArr.slice()
    	targetArr[1].a = 0
    	console.log(arr, targetArr)
  5. Object.assign()
    let targetArr = [1, {a: 1, b:2}, 3]
    	let arr = Object.assign([], targetArr)
    	targetArr[1].a = 0
    	console.log(arr, targetArr)
  6. Array.from()
var arr = [1, 2, 3, {a: 1}]
	var arr1 = Array.from(arr)
	arr[3].a = 2
	console.log(arr1[3].a)

2、深克隆

  1. JSON.parse() 方法与对象同样,也是不能复制函数,区别在于新数组中函数所在位置是个null,对象中则不进行任何处理
    let targetArr = [1, {a: 1, b:2}, 3, function(){console.log(111)}]
    	let arr = JSON.parse(JSON.stringify(targetArr))
    	targetArr[1].a = 0
    	console.log(arr, targetArr)
相关文章
相关标签/搜索