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

更新日期: 2019-11-15阅读: 2.2k标签: 复制

引子:表单数据的克隆

工作中我们需要用到对象或者数组的复制功能

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

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


深克隆和浅克隆的区别

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

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

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


Array&Object通用深克隆方法

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

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

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

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

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克隆

一、浅克隆

Object.assign({}, targetObj) 
let targetObj = {
  a: [1, 2],
  b: 2
}
let obj = Object.assign({}, targetObj)
targetObj.a[0] = 0
console.log(obj)
遍历目标对象的属性,赋给新的对象
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)
通过上面的代码可知,此方法也是浅克隆
es6的扩展运算符...
let targetObj = {
  a: [1, 2],
  b: 2,
  c: function () {
consle.log(333)
  }
}
let obj = {...targetObj}
targetObj.a[0] = 0
console.log(obj, targetObj)


二、深克隆

JSON.parse

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

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克隆

一、浅克隆

数组遍历赋值
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)
concat
let targetArr = [1, {a: 1, b:2}, 3]
let arr = targetArr.concat()
targetArr[1].a = 0
console.log(arr, targetArr)
es6扩展运算符...
let targetArr = [1, {a: 1, b:2}, 3]
let arr = [...targetArr]
targetArr[1].a = 0
console.log(arr, targetArr)
slice
let targetArr = [1, {a: 1, b:2}, 3]
let arr = targetArr.slice()
targetArr[1].a = 0
console.log(arr, targetArr)
Object.assign()
let targetArr = [1, {a: 1, b:2}, 3]
let arr = Object.assign([], targetArr)
targetArr[1].a = 0
console.log(arr, targetArr)


二、深克隆

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)

链接: https://fly63.com/article/detial/6451

原生Js实现复制(Copy)的方法总结,execCommand和clipboardData的使用

原生Js实现复制(Copy)的两种方法,一种是利用 clipboardData,另外一种则是用 execCommand(),今天将统一讲解一下关于他们的使用方法。

网页不让用户复制方法总汇,设置html禁止选择,保护源码,js禁止复制文字

这篇文章主要讲解:右键复制失效方法、菜单-文件-另存为-失效方法、防止查看源代码进行复制的方法、防止页面缓存的方法。来达到一定的代码保护效果

Js使用Object.assign()对象的复制、合并、封装等操作

Js使用Object.assign()对象的复制:Object.assign()只对顶层属性做了赋值,Object.assign()合并/封装等操作:具有相同属性的其他对象覆盖;null、undefined会被忽略;字符串会被封装成单字符的可枚举属性数组

程序员_代码神注释鉴赏大全(可复制粘贴)

程序员个性注释,让你的代码飞起来。一时兴起就收集了以下神注释,希望能为广大ITer带来快乐,以下是收集了以下神注释,希望能为广大程序员们带来快乐,缓解你们工作中的压力

Vue中结合clipboard实现复制功能

首先现在Vue中引入clipboard,在需要使用的组件中import 引入clipboard.不论是单按钮复制还是多按钮复制,一定要在页面加载DOM完成后先New出来具有复制功能的按钮,如果在函数内再New那么可能会出现点击复制按钮两次,才复制成功的现象

原生js实现复制内容到剪切板,兼容pc、移动端(支持Safari浏览器)

在开发中经常会遇到这样的需求,第一种就是点击复制当前页面的链接,第二种就是类似卡券的功能,需要复制密码等等。纯js实现复制文本并提示复制成功(干货)适用所有浏览器

原生JS在网页上复制的所有文字后面自动加上一段版权声明

不少技术博客有这样的处理,当我们复制代码的时候,会自动加上一段本信息版权为XXXX,这是怎么实现的呢?其实实现的方式很简单,可以在我的网站页面上绑定一个 copy 事件,当你复制文章内容的时候

如何设置网页无法复制?

javascript设置网页无法复制的方法:在JavaScript代码中设置禁用右键菜单、复制、选择等操作,禁用Ctrl+c和Ctrl+v快捷键的使用,通过这种方法就可以实现网页无法复制。

HTML页面 用CSS实现禁止选中、复制和右键

最近在写页面的时候,需要在左上角加一个logo,但是复制的时候会把这张图片一块选中。那么我们可以通过CSS给它设置禁止选中,代码如下:

css如何设置不可复制?

css可以使用user-select属性来设置不可复制,此属性可以设置或检索是否允许用户选中文本,将此属性的属性值设置为none可以使文本不可选中。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!