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

❤️❤️❤️Question025 -JavaScript、合并对象有哪些方法?介绍一下深拷贝和浅拷贝 #25

Open
wangbinze opened this issue Mar 9, 2021 · 1 comment

Comments

@wangbinze
Copy link
Owner

wangbinze commented Mar 9, 2021

题目:合并对象有哪些方法?介绍一下深拷贝和浅拷贝

@wangbinze wangbinze changed the title ❤️❤️❤️Question025 -JavaScript、合并对象有哪些方法? ❤️❤️❤️Question025 -JavaScript、合并对象有哪些方法?介绍一下深拷贝和浅拷贝 Mar 9, 2021
@wangbinze
Copy link
Owner Author

把源对象所有的本地属性一起复制到目标对象上。有时候这种操作也被称为“混入”(mixin),因为目标对象通过混入源对象的属性得到了增强。

Object.assign()

  • 接收一个目标对象和一个或对各源对象作为参数,然后将每个源对象中可枚举(Object.propertyIsEnumerable()返回 true)和自有(Object.hasOwnProperty()返回 true)属性复制到目标对象。
  • 以字符串和符号为键的属性会被复制。对每个符合条件的属性,这个方法会使用源对象上的[[Get]]取得属性的值,然后使用目标对象上的[[Set]]设置属性的值。
  • 针对深拷贝,需要使用其他办法,因为 Object.assign()拷贝的是(可枚举)属性值。假如源值是一个对象的引用,它仅仅会复制其引用值。(当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝。) 。
  • Object.assgin() 实际上对每个源对象执行的是浅复制。

深拷贝和浅拷贝(此处只针对对象,不包括数组)

深拷贝和浅拷贝主要针对于引用类型数据,因为基本数据类型赋值后,改变新数据,不会影响到原来的数据;而引用数据类型赋值后,改变新数据,将会影响到原来的数据,此时应该使用深拷贝和浅拷贝定义出一个跟原数据一样但互不影响的数据。
注意:赋值操作和深拷贝浅拷贝不是一回事。

  • 深拷贝
    • 浅拷贝是将原数据中所有的数据复制一份,放到新的变量空间中,两个变量不共享一个内存地址。
    1. 利用json数据和json字符串之间的转换
      先将需要拷贝的对象进行JSON字符串化,然后再pase解析出来,赋给另一个变量,实现深拷贝。
      but:JSON在执行字符串化的这个过程时,会先进行一个JSON格式化,获得安全的JSON值,因此如果是非安全的JSON值,就会被丢弃掉。其中undefined、function、symbol这三种类型的值就是非安全的(包括该对象的属性循环赋值该对象),所以格式化后,就被过滤掉了,而set、map这种数据格式的对象,也并没有被正确处理,而是处理成了一个空对象。
      将含有闭环的对象进行JSON序列化,爆出了错误。
      so:
        let test = {name: 'test'}
        let data = {
            a: '123',
            b: 123,
            c: true,
            d: [43, 2], 
            e: undefined,
            f: null,
            g: function() {    
                console.log("g");  
            },
            h: new Set([3, 2, null]),
            i: Symbol("fsd"),
            j: test,
            k: new Map([
                ["name", "张三"],
                ["title", "Author"]
            ])
        };
        <!-- 比较好的方式 -->
        function deepCopy(obj){ 
            if(typeof obj === 'function'){   
                throw new TypeError('请传入正确的数据类型格式')
            }
            try {
                let data = JSON.stringify(obj)
                let newData = JSON.parse(data)
                return newData
            } catch(e) {
                console.log(e)
            }
        }
    1. 利用递归遍历
      此处参看掘金文章:https://juejin.cn/post/6844904042322198541
  • 浅拷贝
    • 就是不管原数据中值是什么类型的数据,拷贝后的新数据跟原数据是完全没有关联的。
    • Object.assgin()

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