资讯专栏INFORMATION COLUMN

JavaScript中的深浅拷贝

dantezhao / 698人阅读

摘要:深浅拷贝从上面的例子可以发现,如果给一个变量赋值一个对象,那么两者的值会是同一个引用,其中一方改变,另一方也会相应改变。此时需要深拷贝上场深拷贝深拷贝最简单的实现办法就是使用来解决。发现只拷贝了而忽略了和。

深浅拷贝
let a = {
    age: 1
}
let b = a
a.age = 2
console.log(b.age) // 2

从上面的例子可以发现,如果给一个变量赋值一个对象,那么两者的值会是同一个引用,其中一方改变,另一方也会相应改变。

解决这个问题,可以引入浅拷贝:

浅拷贝

可以使用Object.assign 来解决这个问题

let a = {
    age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) // 1

使用ES6展开运算符(...)解决

let a = {
    age: 1
}
let b = {...a}
a.age = 2
console.log(b.age) // 1

通常浅拷贝能解决大部分的问题,但是当遇到,对象里面嵌套一个对象的时候,就需要用到深拷贝了

let a = {
    age: 1,
    name: {
        first: "black"
    }
}
let = {...a}
a.name.first = "guyue"
console.log(b.name.first) // guyue

这样说明浅拷贝并没有对嵌套的对象生效。此时需要深拷贝上场:

深拷贝

深拷贝最简单的实现办法就是使用JSON.parse(JSON.stringify(object)) 来解决。

let a = {
    age: 1,
    name: {
        first: "black"
    }
}
let b = JSON.parse(JSON.stringify(a))
a.name.first = "guyue"
console.log(b.name.first) // black

但是当出现以下几种情况的时候,会出现问题:

let obj = {
    a: 1,
    b: {
        c: 2
    }
}
obj.c = obj.b
obj.d = obj.a
obj.b.c = obj.c
let newObj = JSON.parse(JSON.stringify(obj))
console.log(newObj)
// Uncaught TypeError: Converting circular structure to JSON

报错了,不能解决循环引用对象的问题。

let obj = {
       age: undefined,
    sex: function(){},
    name: "black"
}
let newObj = JSON.parse(JSON.stringify(obj))
console.log(newObj) // {name: "black"}

发现只拷贝了name ,而忽略了undefinedfuncion

所以,JSON.parse(JSON.stringify(obj))遇到这几种情况会出现问题:

不会拷贝 undefined

不能拷贝函数

不能解决循环引用的对象

所以采用下面的方式:

function deepClone(obj) {
    let res = obj instanceof Array ? [] : {}
    for(let k in obj) {
        res[k] = obj[k]
        if(typeof obj[k] === Object) {
            deepClone(obj[k])
        }
    }
    return res
}

let obj = {
       age: undefined,
    sex: function(){},
    name: "black"
}

let newObj = deepClone(obj)
console.log(newObj) // {age: undefined, sex: ƒ, name: "black"}

可以采用ES2017的新语法:

function copyObject(orig) {
  return Object.create(
    Object.getPrototypeOf(orig),
    Object.getOwnPropertyDescriptors(orig)
  );
}

let obj = {
       age: undefined,
    sex: function(){},
    name: "black"
}

let newObj = copyObject(obj)
console.log(newObj) // {age: undefined, sex: ƒ, name: "black"}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/97019.html

相关文章

  • Javascript对象的深浅拷贝

    摘要:开门见山,有人叫对象的复制为深复制浅复制,也有人叫深拷贝浅拷贝。高级属性修改深拷贝满足对象的复制,浅拷贝影响原数组。关于对象的深浅拷贝,暂且探索到这里,后续有新发现再进行补充。 showImg(https://segmentfault.com/img/remote/1460000014305581); 开门见山,有人叫对象的复制为深复制浅复制,也有人叫深拷贝浅拷贝。其实都是copy。 ...

    qieangel2013 评论0 收藏0
  • JavaScript 中的深浅拷贝

    摘要:基本类型指的是简单的数据段,而引用类型指的是一个对象保存在堆内存中的地址,不允许我们直接操作内存中的地址,也就是说不能操作对象的内存空间,所以,我们对对象的操作都只是在操作它的引用而已。 工作中经常会遇到需要复制 JavaScript 数据的时候,遇到 bug 时实在令人头疼;面试中也经常会被问到如何实现一个数据的深浅拷贝,但是你对其中的原理清晰吗?一起来看一下吧! 一、为什么会有深浅...

    Tonny 评论0 收藏0
  • 复习Javascript专题(四):js中的深浅拷贝

    摘要:基本数据类型的复制很简单,就是赋值操作,所以深浅拷贝也是针对,这类引用类型数据。它会抛弃对象的。另外,查资料过程中还看到这么一个词结构化克隆算法还有这一篇资料也有参考,也写得比较详细了的深浅拷贝 基本数据类型的复制很简单,就是赋值操作,所以深浅拷贝也是针对Object,Array这类引用类型数据。 浅拷贝对于字符串来说,是值的复制,而对于对象来说则是对对象地址的复制;而深拷贝的话,它不...

    MobService 评论0 收藏0
  • 深浅拷贝

    摘要:深复制实现代码如下第一种方法通过递归解析解决第二种方法通过解析解决作者六师兄链接原生深拷贝的实现处理未输入新对象的情况通过方法构造新的对象 深浅拷贝针对的是 对象类型,如果是字符串的数组用[...arr],还是不会影响 要区分针对数组的深浅拷贝(默认情况为里面没有对象的数组),与针对对象的深浅拷贝 JavaScript数组深拷贝和浅拷贝的两种方法 let a1 = [1, 2]; ...

    Karrdy 评论0 收藏0
  • JavaScript基础心法——深浅拷贝

    摘要:原文地址基础心法深浅拷贝欢迎。上面的代码是最简单的利用赋值操作符实现了一个浅拷贝,可以很清楚的看到,随着和改变,和也随着发生了变化。展开运算符结论实现的是对象第一层的深拷贝。 原文地址:JavaScript基础心法——深浅拷贝 欢迎star。 如果有错误的地方欢迎指正。 浅拷贝和深拷贝都是对于JS中的引用类型而言的,浅拷贝就只是复制对象的引用,如果拷贝后的对象发生变化,原对象也会发生...

    keithxiaoy 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<