复制基本数据类型不会有什么问题,但是如果是引用数据类型,就会相互之间影响。
一般在数据结构比较简单的情况下,使用浅拷贝就可以达到需求,如果数据结构比较复杂,就必须使用深拷贝。
浅拷贝:
第一种: 使用 for...in来进行浅拷贝
var book = { name: 'JS修炼' } var obj = {} for (var v in book) { obj[v] = book[v] } book.name = '我是book'
第二种: 使用Object.assign进行浅拷贝
var book = { name: 'JS修炼' } var obj2 = Object.assign({},book)
在修改了book里面的数据后,不会影响到新拷贝的数据,这样就实现了浅拷贝
但是在使用浅拷贝的时候,如果对象里面还包含别的引用类型,那么如果修改这里面的对象,就会影响到拷贝的数据
var book = { name: 'JS修炼', list: { a: '我是a', b: '我是b', c: '我是c' } } var obj = {} for (var v in book) { obj[v] = book[v] } var obj2 = Object.assign({},book) book.name = '我是book' book.list.a = '我是修改book'
得到的结果,会影响拷贝到的数据
深拷贝:
第一种:将数据转为字符串的形式然后再进行解析
var book = { name: 'JS修炼', list: { a: '我是a', b: '我是b', c: '我是c' } } var obj = JSON.parse(JSON.stringify(book)); book.name = '我是book' book.list.a = '我是修改book' console.log(book,'book') console.log(obj,'obj')
这种确实比较简单的实现了深拷贝,但是存在一个问题,不能去拷贝function,或者是空的
第二种: 递归的方式进行深拷贝
简单的递归方式
var book = { name: 'JS修炼', age: '', age2: undefined, list: { a: '我是a', b: '我是b', c: '我是c' }, function () { } } function copy (obj) { var o = {} for (var i in obj) { if (typeof obj[i] === 'object') { o[i] = copy(obj[i]) } else { o[i] = obj[i] } } return o; } var obj2 = copy(book) book.name = '我是book' book.list.a = '我是修改book' console.log(book,'book') console.log(obj2,'obj2')
这样简单的递归方式就实现了深拷贝,但是这样写存在一个问题,对数组无法做到处理
完整的代码如下
var book = { name: 'JS修炼', age: '', age2: undefined, list: { a: '我是a', b: '我是b', c: '我是c' }, author:['作者1','作者2'], author2:[ { value: '我是author2' } ], function () { } } function clone (obj) { var vv = null; if (typeof obj == 'object' && obj !== null) { vv = obj instanceof Array ? [] : {} for (var v in obj) { vv[v] = clone(obj[v]) } } else { vv =obj } return vv; } var obj3 = clone(book) book.name = '我是book' book.list.a = '我是修改book' book.author[0] = 'w' book.author2[0].value = 'w'