JS深拷贝碰到的问题

js的数据类型有:Null Undefined Boolean Number Array String Object 之分,es6后又增加了Symbol,

其中分为2大类:基本数据类型和对象类型,同时产生了相应的2个传值方式:赋值和引用;

基本数据类型的深拷贝

JSON.parse(JSON.stringify(obj))

通过简单函数

function extendCopy(p) {
  var c = {};
  for (var i in p) {
    c[i] = p[i];
  }
  return c;
}

引用类型深拷贝

引用类型细分

  • 基本的JS对象:正则,函数,对象,数组等之分
  • 其他JS内置的Date,Error,Math等
  • 浏览器内置的window,document等

严格来说,这些对象赋值时都是要考虑的,但常见的对象内部存放的数据类型不会涵盖的这么全面,

但也需要考虑:正则,函数,对象,数组,Dete,Dom

数据类型的识别办法

var type=Object.prototype.toString.call(Obj).split(/[[s]]/)[2]

通过识别type可以确认数据的类型,然后分别针对Array,Object做不同的处理

let obj1 = {
  a: 11,
  b: 'bb',
  c: new Date(),
  d: function aa () {return 2},
  e:[1,2,3],
  f:new Error('error'),
  g:document.body,
  h:new RegExp(/[111]/)
}
function deepCopy (obj) {
  var type = Object.prototype.toString.call(obj).split(/[[s]]/)[2];
let temp = type === 'Array' ? [] : type=='Object'? {}:obj;
if(type=='Array' || type=='Object'){
  for (let val in obj) {
    temp[val] = typeof obj[val] == 'object' ? deepCopy(obj[val]) : obj[val]
  }
}
  return temp
}

如上,实现了深拷贝

但深拷贝还有一个坑要填

那就是循环赋值问题;回到前面的

···

let obj1 = {

a: 11,

b: ‘bb’,

c: new Date(),

d: function aa () {return 2},

e:[1,2,3],

f:new Error(‘error’),

g:document.body,

h:new RegExp(/[111]/),

}

obj1.g=obj1

deepCopy(obj1)

//Uncaught RangeError: Maximum call stack size exceeded

at RegExp.[Symbol.split] ()

at String.split (native)

at deepCopy (:12:50)

at deepCopy (:16:47)

at deepCopy (:16:47)

at deepCopy (:16:47)

at deepCopy (:16:47)

at deepCopy (:16:47)

at deepCopy (:16:47)

at deepCopy (:16:47)

···

这是就会出现堆栈溢出的错误了。

稿源:Mishe's blog (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 移动互联 » JS深拷贝碰到的问题

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录

登录

忘记密码 ?

切换登录

注册