javascript - 全局变量的值为何被改变了?
巴扎黑
巴扎黑 2017-04-11 12:56:02
[JavaScript讨论组]
var collection = {
    "5439": {
    "album": "ABBA Gold"
    }
};
function updateRecords(id, prop, value) {
  collection1 = collection;
  document.write("begin "+JSON.stringify(collection)+"
"); collection1[id][prop]=value; document.write(JSON.stringify(collection1)+"
"); } updateRecords(5439, "tracks", "Addicted to Love"); updateRecords(5439, "test", "my test");

为何结果是

begin {"5439":{"album":"ABBA Gold"}}
"5439":{"album":"ABBA Gold","tracks":"Addicted to Love"}}
begin {"5439":{"album":"ABBA Gold","tracks":"Addicted to Love"}}
{"5439":{"album":"ABBA Gold","tracks":"Addicted to Love","test":"my test"}}

不是

begin {"5439":{"album":"ABBA Gold"}}    
{"5439":{"album":"ABBA Gold","tracks":"Addicted to Love"}}    
begin {"5439":{"album":"ABBA Gold"}}    
{"5439":{"album":"ABBA Gold","test":"my test"}}

collection是全局变量,我在函数里面也仅仅是对局部变量collection1赋值,collection1的改变,为何影响到了collection?

巴扎黑
巴扎黑

全部回复(5)
天蓬老师

浅拷贝,经常犯的错误。因为原始对象和新对象引用的同一个内存地址,因此改变一个值就会改变另一个的值。
解决办法:

var b = JSON.parse(JSON.stringify(a));// 当然全部会转成String,带有function之类的对象就会有问题

Object.freeze(a);// 建议这个,好像怎么玩都可用
var b = a;

或jquery的extend,反正各种解决办法...

天蓬老师

js中对象中,通过等于号赋值(collection1 = collection),改变其中一个的值,另一个的值也会改变。

PHP中文网

objection1=objection. 这是个引用类型赋值。也实现了是楼上说浅拷贝。
Js语言里面有六种数据类型。基本类型undefined,null,Boolean,String,Number.一种复杂数据类型。
后者在进行赋值拷贝时,赋值的是其引用地址。所有的备份最终访问的还是同一个对象。

伊谢尔伦

这是引用类型,改变一个值会影响另外一个值的~

阿神

基本类型和引用类型的数据储存原理的问题;
这种场景下,建议把源数据,储存为基本类型,然后转为JSON对象就可以了;直接有效;
(根据场景,考虑使用什么类型的)
代码如下;

    //源数据用JSON字符串储存;
    var collection = ['{',
        '        "5439": {',
        '            "album": "ABBA Gold"',
        '        }',
        '    }'].join("");
    function updateRecords(id, prop, value) {
        collection1 = JSON.parse(collection);//JSON字符串转为JSON对象
        document.write("begin "+JSON.stringify(collection1)+"</br>");
        collection1[id][prop]=value;
        document.write(JSON.stringify(collection1)+"</br>");
    }
    updateRecords(5439, "tracks", "Addicted to Love");
    updateRecords(5439, "test", "my test");

上面的代码中的对象转为字符串是用工具生成的;

顺便安利一下,我写的chrome扩展,这个礼拜刚传到chrome应用市场;搜索: HTML To Javascript

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号