多是最全的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)
相關文章
相關標籤/搜索