传址和传值

复杂的数据类型 传址:赋值数据类型会出现传址情况(传递了数据和地址,共享了一块内存空间)浅拷贝:没有拷贝地址节省内存,但是因为共享内存,所有相互影响数据

    let DadPro ={
        name:"张三",
        age:"20",
        sex:"男",
    }    
    let SonPro = DadPro;
    SonPro.name ="李四";
    // console.log(SonPro);    console.log(DadPro.name);  //李四

简单的数据类型– 传值跟深拷贝很像 复制一份A给B (不包括指针, A和B 的内存地址不一样 改变B,A的内容不发生变化)

    let a = 10;
    let b = a;
    b = 20;
    // console.log(a);
    // console.log(b);

解决传址问题相互影响数据
方法一:for 循环数组 将没个参数分别赋值给数组啊arr2
缺点: 当数组中存放了引用数据时,就需要多次循环,比较复杂(遇到复杂数组比较无力)

    let arr1 = [1,3,2,4,5]
    let arr2 = arr1;
    arr2[0] = 10;
    console.log(arr1[0]) //输出10
  	//通过for循环后
    let arr3 = [];
    for (var i=0; i<arr1.length; i++){
        arr3[i] = arr1[i]
    }
    arr3[0] = 8;
    console.log(arr1[0]) //输出1 值不改变

第二种方法 forEach

    let arr4 = [1,2,3,4];
    let arr5 = [];
    let str = '';
    arr4.forEach(function(val){
        console.log(val)
        str += val
    })
    arr5 = str.split('')
    console.log(arr5)
    
    arr5[0]= 10;  
    console.log(arr4[0])  //输出值为1不受影响

第三种方法 返回一个新的对象,但是通过这个方法完成的深拷贝,会丢失函数 和undefined

JSON.stringify()把对象转换成字符串形式的JSON格式字符串值(无法转换BOM和DOM对象)
JSON.parse():把字符串形式的标准JSON字符串转换成对象(属性名必须有引号)

    let arr6=[1,2,3,[2,4],{a:"abc",b:"cc"}]
    // let arr7 = JSON.stringify(arr6);
    // arr6 = JSON.parse(arr7);
    // console.log(arr7)
    // arr7[0] = 10;
    // console.log(arr6[0])

    // 简写
    let arr7 = JSON.parse(JSON.stringify(arr6))
    arr7[0] = 10;
    console.log(arr6[0])

第四种方法:封装一个深拷贝方法 来直接调用

    // 封装一个深拷贝方法 来直接调用    
    let arr7 = deepCopy(arr6);
    arr7[0] = 5;
    console.log(arr6);
    console.log(arr7);

    function deepCopy(obj){
        let newObj = Array.isArray(obj)?[]:{};
        //forin :会遍历对象和原型以及原型链上的方法和属性
        // 但是我们做深拷贝的时候,不需要去拷贝原型链的内容
        for(let key in obj){
            // hasOwnProperty()用来检测指定内容是否是自身 只在自身中寻找,返回值 布尔
            if(obj.hasOwnProperty()){
                // 判断是否是对象(复杂数据类型)
                if(typeof obj[key] === "object"){
                    // 如果内部的数据依然是个对象
                    // 再调用自身,重复检测复值一遍
                    newObj[key] = deepCopy(obj[key])
                }else{ //简单的数据类型  直接复值
                     newObj[key] = obj[key]
                }
            }
        }
        // 最后 将我们检测并赋值的新对象返回!达成新内存的目的
        return newObj;
    }
发布了96 篇原创文章 · 获赞 26 · 访问量 7272

猜你喜欢

转载自blog.csdn.net/weixin_46146313/article/details/104210689
今日推荐