1.对象的特别性
由于对象的是经由过程指针细致内存地点的,所以对象的拷贝不能像变量平常简朴的赋值,对象的赋值只是将指针的地点赋值过去罢了,修正属性值会对一切指向这个内存地点的对象的属性值都会被转变,见下面的例子:
// 变量赋值
var a = 5;
var b = a;
// 修正b不会对a形成影响
b=10;
> a
> 5
// 对象赋值
var obj = {
a: '5',
b: '10',
c: {
d: 1
}
}
var obj1 = obj
// 修正obj1.a会对obj.a形成影响
obj1.a = 9
> obj.a
> 9
所以当你运用object(array也是object的一种特别情势)时,想复制一个object,但两个object互不影响时,这就须要我们说的浅拷贝和深拷贝了
2.最简朴的完成(有局限性)
// object数据中只能有基础的数据范例(String,Number,Boolean,Array,object,null,undefined),别的数据会丧失,但不会报错
obj1 = JSON.parse(JSON.stringify(obj))
3.浅拷贝
基于Object的特别性,在对对象举行简朴的拷贝,只拷贝第一层级的属性,这类拷贝就是浅拷贝。
function Copy(source, obj) {
for (let key in obj) {
source[key] = obj[key]
}
return source
}
Copy(obj1, obj)
obj1.a=10
obj1.c.d=100
// 浅拷贝对第一层的属性举行了拷贝,所以obj.a不受影响
> obj.a = 9
// 然则obj.c.d是第二层级的属性,它受到了影响,它的值被转变了
> obj.c.d =100
3.深拷贝
3.1递归遍历
注重:递归遍历能够爆栈,平常不会涌现这类状况,除非对象的深度到达10000+
// 推断数据范例的要领--更新于2019-03-28
function isType(data, type) {
return Object.prototype.toString.call(data) === '[object ' + type + ']'
}
// extendEasy完成深拷贝;extendSuper在深拷贝的基础上完成多个继续相似(source, obj1, obj2, obj3 ...)
function extendSuper () {
var arg = arguments
for (let i = 1; i < arg.length; i++) {
arg[0] = extendEasy(arg[0], arg[i])
}
return arg[0]
}
// 完成深拷贝
function extendEasy (source, obj) {
for (let key in obj) {
// 本来运用instanceof推断范例会存在BUG
if (isType('Object',obj[key])) {
source[key] = {}
source[key] = extendEasy(source[key], obj[key])
}
if (isType(' Array',obj[key])) {
source[key] = []
source[key] = extendEasy(source[key], obj[key])
}
source[key] = obj[key]
}
return source
}
3.2树遍历(引荐)
注重:下面代码中Object.isType的完成体式格局–>https://segmentfault.com/a/11…
深度和广度:pop跟push决议了深度优先,广度优先请用shift和push
/*
* @param target object 非必填,默许{}
* @param source object 必填
*
* */
function copyObject() {
let root = {}
const obj = arguments[arguments.length]
if(!Object.isType(obj, "Object") && !Object.isType(obj, "Array")) {
throw "source not Object"
}
if(arguments.length >= 2 && (Object.isType(arguments[0], "Object") || Object.isType(arguments[0], "Array"))) {
root = arguments[0]
} else {
if(Object.isType(arguments[0], "Array")) {
root = []
}
}
// 栈
const arr = [
{
// key: undefined,
parent: root,
data: obj
}
]
while (arr.length) {
// arr: pop跟push决议了深度优先,广度优先请用shift和push
const o = arr.pop()
// if(o.key === undefined) {
// o
// }
for (let item in o.data){
if (Object.isType(o.data[item], "Array")){
o.parent[item] = []
arr.push({
key: item,
parent: o.parent[item],
data: o.data[item]
})
}
else if (Object.isType(o.data[item], "Object")) {
o.parent[item] = {}
arr.push({
key: item,
parent: o.parent[item],
data: o.data[item]
})
}
// 假如对别的范例支撑请在这里拓展
else {
o.parent[item] = o.data[item]
}
}
}
return root
}