• 欢迎访问本网站,技术教程,资源分享,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入东蓬莱!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏东部蓬莱吧

JS中变量的存储

前端开发 Jokul 11个月前 (07-15) 672次浏览 0个评论 扫描二维码

问题现象

JS中的变量是保存在栈内存中的

  • 基本数据类型的值直接在栈内存中存储;
  • 值与值之间是独立存在的,修改一个变量不会影响其他变量;
  • 对象(引用数据类型)是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟一个新的空间;
  • 而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,当一个变量修改属性是,另一个也会受到影响;
  • var obj1=new Object();
    obj1.name="mike";
    var obj2=obj1;
    obj2.name=“jack”;
    console.log(obj1.name);//jack
    
  • 当清空一个变量的值时,只是断开该变量与对象的联系,另一个对象并不受影响
  • 当比较两个基本数据类型的值时,就是比较值;
  • 当比较两个引用数据类型时,比较的是对象的内存地址;
  • var a=10;
    var b=10;
    console.log(a==b);//true
    var obj1=new Object();
    var obj2=new Object();
    console.log(obj1==obj2);//false
    

    问题:
    数组乃引用数据类型,因此修改b的值,a也会受影响

    var a=[1,2,3];
    var b=a;
    b[0]=10;
    console.log(a[0]);//10;
    

    解决方案

    使用引用数据类型的深拷贝

    浅拷贝:只遍历一层,如果存在数组成员是对象,[{name:’jack’}],不会对对象里的值进行遍历拷贝。
    其实根据浅拷贝的方法不同,也有不同的效果。

  • 1. 其中最弱的浅拷贝为直接赋值
  • let arr2 = arr1;
    

    是直接将整个arr1数组的地址赋给arr2,故arr2的任意值(为什么说任意值呢?因为后面会介绍到,有些浅拷贝,可以使部分值看上去有深拷贝的效果)改变,都会影响到arr1。

  • 2. 接下来介绍的四种浅拷贝方法就厉害一些了,它们在有些情况(原数组里的数据不包含引用类型)下也能达到深拷贝效果(没错只是披着狼皮的小绵羊啦,本质还是浅拷贝)。
  • 一个数组变化,另一个数组不受影响。
    原数组里的数据不包含引用类型

    let arr1 = [1 , 2 , 3];  //原数组
    
  • 1.使用拓展运算符
  • let arr2 = [...arr1];
    //等价于
    let arr2=[1, 2, 3];
    

    //这也就是它不同于arr2=arr1的地方,

  • 2.使用assign()
  • let arr2 = Object.assign([],arr1);
    
  • 3.使用concat()
  • let arr2 = [].concat(arr1);
    

    因为 concat() 返回的是一个副本,所以这个时候改变 arr1 就不会导致 arr2 改变了。

  • 4.使用slice()
  • let arr2 = arr1.slice(0);
    

    深拷贝:就是不管里面多少层,都遍历,克隆一个与旧不相关的,修改新的不影响旧的。
    原数组里的数据包含引用类型

    let arr1 = [1 , 2 , 3 , {"name" : "张小二"} , {"sex" : "male"}];  //原数组
    

    使用上述方法均不能实现全部深拷贝,非引用类型的值不会受影响,嵌套的一层引用类型的值会受影响。
    解决方法:
    方法一:递归

    let cloneObj = function(obj){
        let str, newobj = obj.constructor === Array ? [] : {};
        if(typeof obj !== 'object'){
            return;
        } else if(window.JSON){
            str = JSON.stringify(obj), //系列化对象
            newobj = JSON.parse(str); //还原
        } else {
            for(var i in obj){
                newobj[i] = typeof obj[i] === 'object' ? 
                cloneObj(obj[i]) : obj[i]; 
            }
        }
        return newobj;
    };
    
    let arr2 = cloneObj(arr1);
    

    方法二:通过JSON解析解决

    let arr2 = JSON.parse(JSON.stringify(arr1));
    

    注意:这种方法拷贝后的数组会丢失原数组中定义的方法和数组原型中定义的方法。


    东部蓬莱 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
    转载请注明原文链接:JS中变量的存储
    喜欢 (1)
    [支付宝]
    分享 (0)
    发表我的评论
    取消评论
    表情 贴图 加粗 删除线 居中 斜体 签到

    Hi,您需要填写昵称和邮箱!

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址