美文网首页
引用值的复制、浅拷贝、深拷贝

引用值的复制、浅拷贝、深拷贝

作者: 云凡的云凡 | 来源:发表于2020-09-14 07:37 被阅读0次
    vue 中父组件通过 v-bind 属性 给子组件传值,子组件通过 props(可以是对象或者数组) 接收,子组件不能修改父组件传过来的值,可以在 data 函数中 新定义一个变量,把传过来的值拷贝到新定义的变量上。当遇到对象时候,就用深拷贝靠谱点。
    所以我们来说说引用值的复制、浅拷贝、深拷贝

    1.复制 :其中一个改变,其它跟着变(只是多了一个变量指向那个空间)

     var cat1 = {
                name: '天天',
                Borth: 2019,
                hobby: 'eat fish',
                friends: '大黑',
                son: {
                    oone: '小花',
                    two: '小淘气',
                    girlFriend: {
                        name: '一一',
                        age: 25
                    },
                    car: '本田'
                }
            }
           // 1.复制
            var cat2 = cat1
            console.log(cat1 === cat2);  //true
            console.log(cat1 == cat2);   //true
            //因为对象是传址的,var cat2 = cat1 只是把对象 cat1 的指针传给 cat2 ,
            // 它们指向的是同一块内存区域,所以 cat1 和 cat2 的值和类型都相等
    
    
            cat2.name = '王王'
            cat2.son.oone = '小李'
            console.log(cat1 === cat2);   //true
            console.log(cat1 == cat2);  //true
            // 当cat2 改变,cat1也会跟着改变。当改变 cat1 时,cat2 也会改变,所以他们的值和类型还是一样。
    

    2.浅拷贝:并没有把对象的引用值处理,值处理了第一层的属性,并没有处理下面的引用值。

        <script>
           Object.prototype.num = 1
            var cat1 = {
                name: '天天',
                Borth: 2019,
                hobby: 'eat fish',
                friends: '大黑',
                son: {
                    oone: '小花',
                    two: '小淘气',
                    girlFriend: {
                        name: '一一',
                        age: 25
                    },
                    car: '本田'
                }
            }
    
    
            var cat2 = {}
            // 2.浅拷贝
            simpleClone(cat1, cat2)
            function simpleClone(origin, target) {
                 // var target = target || {}
                for (var key in cat1) {
                   //把原型剔除出去
                    if (origin.hasOwnProperty(key)) {
                        target[key] = origin[key]
                    }
                }
            }
         
            console.log(cat1 === cat2);  //false
            console.log(cat1 == cat2);  //false
    
            // 当改变对象里面引用值的时候:另一个会跟着改变
            cat1.son.two = '淘气'
            console.log(cat1.son.two); //淘气
            console.log(cat2.son.two);  //淘气
            console.log(cat1 === cat2);   //false
            console.log(cat1 == cat2);       //false
    
            // 当改变对象里的基础类型:另一个不会跟着改变
            cat1.Borth = 2020
            console.log(cat1.Borth);  //2020
            console.log(cat2.Borth);  //2019
            console.log(cat1 === cat2);   //false
            console.log(cat1 == cat2);   //false
        </script>
    

    3.深拷贝:有引用值的时候就要做一系列遍历,在循环的时候去判断里面的每一项键值对是不是引用值,是引用值的时候再判断是数组函数对象,用一个递归的克隆函数来进行再处理。

     <script>
            Object.prototype.num = 1
            var cat1 = {
                name: '天天',
                Borth: 2019,
                hobby: 'eat fish',
                friends: '大黑',
                son: {
                    oone: '小花',
                    two: '小淘气',
                    girlFriend: {
                        name: '一一',
                        age: 25
                    },
                    car: '本田'
                }
            }
    
            var cat2 = deepClone(cat1)
            console.log(cat2);
            cat2.name = 'zhangsan'
            cat2.son.two = '李四'
            console.log(cat1);
            console.log(cat2);
    
            function deepClone(origin, target) {
                var target = target || {}
                toStr = Object.prototype.toString
                arrType = '[object Array]'
                for (var key in origin) {
                    if (origin.hasOwnProperty(key)) {
                        if (typeof (origin[key] === 'object') && origin[key] !== null) {
                            if (toStr.call(origin[key]) === arrType) {
                                target[key] = []
                            } else {
                                target[key] = {}
                            }
                            deepClone(origin[key], target[key])
                        } else {
                            target[key] = origin[key]
                        }
                    }
                }
                return target
            }
        </script>
    

    或者

    export const getObjType = obj => {
        let toString = Object.prototype.toString
        let map = {
            '[object Boolean]': 'boolean',
            '[object Number]': 'number',
            '[object String]': 'string',
            '[object Function]': 'function',
            '[object Array]': 'array',
            '[object Date]': 'date',
            '[object RegExp]': 'regExp',
            '[object Undefined]': 'undefined',
            '[object Null]': 'null',
            '[object Object]': 'object'
        }
        if (obj instanceof Element) {
            return 'element'
        }
        return map[toString.call(obj)]
    }
    
    export const deepClone = data => {
        let type = getObjType(data)
        let obj
        if (type === 'array') {
            obj = []
        } else if (type === 'object') {
            obj = {}
        } else {
            // 不再具有下一层次
            return data
        }
        if (type === 'array') {
            for (let i = 0, len = data.length; i < len; i++) {
                obj.push(deepClone(data[i]))
            }
        } else if (type === 'object') {
            for (let key in data) {
                obj[key] = deepClone(data[key])
            }
        }
        return obj
    }
    

    4.json深拷贝:不常用,因为json数据没有方法

     <script>
            var cat1 = {
                name: '张三',
                Borth: 2019,
                hobby: '乒乓球',
                friends: '李四',
                son: {
                    oone: '小花',
                    two: '小淘气',
                    girlFriend: {
                        name: '一一',
                        age: 25
                    },
                    car: '本田'
                },
                eat: ['鱼', '胡萝卜', '玉米']
            }
            var str = JSON.stringify(cat1)  //把对象转换成字符串,这样就不是引用值了
            var cat2 = JSON.parse(str)
            cat2.name = '王五'
            cat2.eat.push('土豆')
            var cat2 = JSON.parse(str)
            console.log(cat1, cat2)
            console.log(cat1 === cat2); //false
            console.log(cat1 == cat2); //false
        </script>
    

    相关文章

      网友评论

          本文标题:引用值的复制、浅拷贝、深拷贝

          本文链接:https://www.haomeiwen.com/subject/jdeaektx.html