V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
MonkeyD1
V2EX  ›  JavaScript

请教个 JavaScript 问题

  •  1
     
  •   MonkeyD1 · 2021-05-08 15:50:20 +08:00 · 1737 次点击
    这是一个创建于 1330 天前的主题,其中的信息可能已经有所发展或是发生改变。
    function bubbleSort(arr, b) {
    let newArr = arr.map(v => v),max = newArr.length - 1;
    for (let j = 0; j < max; j++) {
    for (let i = 0; i < max - j; i++) {
    if (newArr[i].id > newArr[i + 1].id) {
    let temp = newArr[i].id;
    newArr[i].id = newArr[i + 1].id;
    newArr[i + 1].id = temp;
    }
    }
    }
    return newArr;
    }

    let arr = [{ id: 4 }, { id: 2 }, { id: 3 }, { id: 9 }];

    console.log(arr); // [{id: 2},{id: 3},{id: 4},{id: 9}]
    console.log(bubbleSort(arr)); // [{id: 2},{id: 3},{id: 4},{id: 9}]
    console.log(arr); // [{id: 2},{id: 3},{id: 4},{id: 9}]

    排序 为什么原始的 arr 也被修改了
    10 条回复    2021-05-08 17:50:09 +08:00
    JK9993
        1
    JK9993  
       2021-05-08 16:00:00 +08:00   ❤️ 1
    因为你修改的是对象的 id,而不是交换新数组里元素的位置。新数组里的对象引用的还是原来的。另外当前场景下 Array.prototype.slice 比 map 更合适
    MonkeyD1
        2
    MonkeyD1  
    OP
       2021-05-08 16:00:23 +08:00
    大意了 我自己发的帖子 我自己也不能删😑
    MonkeyD1
        3
    MonkeyD1  
    OP
       2021-05-08 16:04:38 +08:00
    @JK9993 感谢🤦‍♂️, 我以为 有一层 map 已经拷贝了 没想到里面的对象 拷贝的还是指针 我去看看 slice
    MonkeyD1
        4
    MonkeyD1  
    OP
       2021-05-08 16:11:48 +08:00
    已解决 let newArr = JSON.parse(JSON.stringify(arr));
    liyang5945
        5
    liyang5945  
       2021-05-08 16:15:11 +08:00 via Android
    newArr = arr.concat()
    MonkeyD1
        6
    MonkeyD1  
    OP
       2021-05-08 16:17:00 +08:00
    @liyang5945 不行的噢 需要深拷贝
    liyang5945
        7
    liyang5945  
       2021-05-08 16:26:17 +08:00
    @MonkeyD1 #6 上面那句就是深拷贝,不会改变原数组,你可以试下
    chogath
        8
    chogath  
       2021-05-08 16:26:54 +08:00   ❤️ 1
    JSON.parse(JSON.stringify(object)) 存在一些不足,例如:

    1. 拷贝的对象的值中如果有函数, undefined, symbol,则经过 JSON.stringify() 序列化后的 JSON 字符串中这个键值对会消失
    2. 无法拷贝不可枚举的属性,无法拷贝对象的原型链
    3. 拷贝 Date 引用类型会变成字符串
    4. 拷贝 RegExp 引用类型会变成空对象
    5. 无法拷贝对象的循环引用(即 obj[key] = obj)

    所以还是建议你直接手写,或者用第三方库,例如:lodash.cloneDeep
    christin
        9
    christin  
       2021-05-08 17:48:34 +08:00 via iPhone   ❤️ 1
    @liyang5945
    concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
    concat 并不是深拷贝 而是返回新数组

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/concat
    christin
        10
    christin  
       2021-05-08 17:50:09 +08:00 via iPhone
    @christin 所以才不会改变原数组
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2470 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 04:42 · PVG 12:42 · LAX 20:42 · JFK 23:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.