Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS深拷贝碰到的问题 #155

Open
mishe opened this issue Mar 16, 2017 · 0 comments
Open

JS深拷贝碰到的问题 #155

mishe opened this issue Mar 16, 2017 · 0 comments

Comments

@mishe
Copy link
Owner

mishe commented Mar 16, 2017

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)
···

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant