Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 620|回复: 0

用浅/深拷贝、和HTML5方法解决js对象的引用的问题

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-6-30 11:29:06 | 显示全部楼层 |阅读模式

    先来看一个例子

    例一:

    var a=[1,2,3];
    var b=a;
    b.push(4);
    alert(b);//1,2,3,4
    alert(a);//1,2,3,4
    var a=[1,2,3];
    var b=a;
    b=[1,2,3,4]
    alert(b);//1,2,3,4
    alert(a);//1,2,3

    这两种方法得出的结果是不一样的。

    第一个程序,是对象的引用, 把a的值附给b,a与b之间是引用的关系,当两者之间是引用的关系时,改变任一变量,都会影响另一个变量。

    第二个程序,只是对b的值改变,虽然b=a ,但是当改变b的值时,又重新建立了一个地址,这个地址与a无关,所以在改变b值时,与a无关,这有点类似于C中的指针

    再来看一个例子

    例二:

    var a={
         name:'hello'          
    };
    var b=a;
    b.name='hi';
    alert(a.name);//当然了,这个结果肯定是hi

    如何解决上面的问题呢?

    var a={
         name:'hello'          
    };
    function copy(a){
        var b={};
        for(var attr in a){
            b[attr]=a[attr]
        }    
       return b  
    }
    copy(a).name='hi';
    alert(a.name); //这时的结果就是hello了
            

    上面的方法叫浅拷贝,利用for in 把a中属性拷贝给b,但是只是拷贝了一个副本,实际上当修改b的值是不会改变a的值的。当然有浅拷贝就有深拷贝。

    var a={
         name:{value:'world'}          
    }
    function copy(a){
        var b={};
        for(var attr in a){
            b[attr]=a[attr];
        }    
       return b  
    }
    copy(a).name.value='space';
    alert(a.name.value); //这时的结果是space

    这时候大家或许或纳闷,用了拷贝了怎么结果还是space呢!因为JSON里面又有一个 value:'world' 这个类型是一个对象,你拷贝过来还是对象,还是对象的引用,所以结果就是space,当然了,或许有会说那就再用一次copy就行。由结果再调用一次copy,对了,就是递归的含义,在函数内部调用函数本身。稍微修改一下程序即可

    var a={
         name:{value:'world'}          
    }
    function deepCopy(a){
         if(typeof a!='object'){
            return a
        }   
        var b={};
        for(var attr in a){
            b[attr]=deepCopy(a[attr]);
        }    
       return b  
    }
    deepCopy(a).name.value='space';
    alert(a.name.value); //这时的结果就是world

    改的地方有两处,1、执行函数内部调用函数本身   b[attr]=deepCopy(a[attr])   2、终止条件typeof a!='object'  就像上面说的,你用浅拷贝拷的是对象,终止条件就是检测类型不是对象的时候,返回a的值。这样就解决了问题。 上面的方法就是深拷贝

    例三:

    现在了解了浅/深拷贝,想用HTML5方法去解决。在解决之前,我们很有必要去了解HTML5之前如何将字符串转换成js语句,如下:

    var str='function task(){alert('hello')}'
    var fn=eval(str);
    task(); //hello

    HTML5如何把JSON格式的字符串转成JSON对象,用JSON.parse() 如下:

    var a='{
      'name':'hello';  
    };'
    var json=JSON.parse(a);
    alert(json.name); //hello

    这个name上加了 ' '  不加' ' 是不严格的JSON,JSON.parse 方法要求必须是严格的JSON

    如何将JSON对象转成JSON格式的字符串呢,用JSON.stringify()  如下:

    var a={
       name:'hello'  
    };
    var json=JSON.stingify(a);
    alert(json); // '{'name':'hello'}'
    这时的结果就是 '{'name':'hello'}',这时候就明白了为什么要用严格的JSON格式了

    那么用HTML5怎么解决问题呢,那就先把JSON转成字符串,再把JSON格式的字符换转成对象,实际上引用的还是a的副本,并没有真正引用a。这就和拷贝中的
    副本原理是一样的。如下:
    var a={
        name:'hello'  
    };
    var str=JSON.stringify(a);
    var obj=JSON.parse(str);
    var b=obj;
    b.name='hi';
    alert(a.name);//hello
    拓展:

       这种方法实际上在8以下是不兼容的,如何兼容呢,就是引用一个json文件:json2.js,如下

    <script type='text/javascript' src='json2.js'></script>

     

     

     

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-23 08:25 , Processed in 0.059058 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表