js实现数组浅拷贝和深拷贝

js实现数组浅拷贝和深拷贝JavaScript 实现数组的深拷贝 浅拷贝 vararr old 1 true null undefined varnew arr arr concat 或者 varnew arr arr slice 也是一样的效果 new arr 0 new console log arr ol

浅拷贝:创建一个新的对象,来接受重新复制或引用的对象值。如果对象属性是基本的数据类型,复制的就是基本类型的值给新对象;但如果属性是引用数据类型,复制的就是内存中的地址,如果其中一个对象改变了这个内存中的地址,会影响到另一个对象,因为两者共同指向同一个地址。

数组的浅拷贝
可用concat、slice返回一个新数组的特性来实现拷贝

var arr = ['old', 1, true, null, undefined]; var new_arr = arr.concat(); // 或者var new_arr = arr.slice()也是一样的效果; new_arr[0] = 'new'; console.log(arr); // ["old", 1, true, null, undefined] console.log(new_arr); // ["new", 1, true, null, undefined] 

浅拷贝,还可以用Object.assign()方法实现

let target = { 
   }; let source = { 
    a: { 
    b: 2 } }; Object.assign(target, source); console.log(target); // { a: { b: 10 } };  source.a.b = 10; console.log(source); // { a: { b: 10 } };  console.log(target); // { a: { b: 10 } }; 

但是如果数组嵌套了对象或者数组的话用concat、slice拷贝只要有修改会引起新旧数组都一起改变了,比如:

var arr = [{ 
   old: 'old'}, ['old']]; var new_arr = arr.concat(); arr[0].old = 'new'; new_arr[1][0] = 'new'; console.log(arr); // [{old: 'new'}, ['new']] console.log(new_arr); // [{old: 'new'}, ['new']] 

下面是浅拷贝一个通用方法,实现思路:遍历对象,把属性和属性值都放在一个新的对象里

var shallowCopy = function (obj) { 
    // 只拷贝对象 if (typeof obj !== 'object') return; // 根据obj的类型判断是新建一个数组还是一个对象 var newObj = Array.isArray(obj) ? [] : { 
   }; // 遍历obj,并且判断是obj的属性才拷贝 for (var key in obj) { 
    if (obj.hasOwnProperty(key)) { 
    newObj[key] = obj[key]; } } return newObj; } 

数组的深拷贝
方法一:JSON.stringify()不仅可拷贝数组还能拷贝对象(但不能拷贝函数,也不能解决循环引用问题)

var arr = ['old', 1, true, ['old1', 'old2'], { 
   old: 1}] var new_arr = JSON.parse(JSON.stringify(arr)) console.log(new_arr); 

方法二:递归。下面是深拷贝一个通用方法,实现思路:拷贝的时候判断属性值的类型,如果是对象,继续递归调用深拷贝函数

var deepCopy = function(target) { 
    // 只拷贝对象 if (typeof target !== 'object') return target; // 根据obj的类型判断是新建一个数组还是一个对象 var result = Array.isArray(obj) ? [] : { 
   }; for (var key in target) { 
    // 遍历obj,并且判断是obj的属性才拷贝(不能拷贝原型对象的属性) if (target.hasOwnProperty(key)) { 
    // 判断属性值的类型,如果是对象递归调用深拷贝 result[key] = typeof target[key] === 'object' ? deepCopy(target[key]) : target[key]; } } return result; } 
var deepCopy = function (target, map = new Map()) { 
    // 只拷贝对象 if (typeof target !== "object") return target; // 克隆数据之前,先判断之前是否有克隆过(解决循环引用的问题) let cache = map.get(target); if (cache) { 
    return cache; } // 根据obj的类型判断是新建一个数组还是一个对象 var result = Array.isArray(target) ? [] : { 
   }; // 将新的结果存到容器中 map.set(target, result); for (var key in target) { 
    // 遍历obj,并且判断是obj的属性才拷贝(不能拷贝原型对象的属性) if (target.hasOwnProperty(key)) { 
    // 判断属性值的类型,如果是对象递归调用深拷贝 result[key] = typeof target[key] === "object" ? deepCopy(target[key], map) : target[key]; } } return result; }; // 测试代码 let obj = { 
    a: 1, b: [6, 8], c: { 
    e: 3 } }; obj.b.push(obj.c); obj.c.h = obj.b; let obj1 = deepCopy(obj); console.log(obj); console.log(obj1); 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/221899.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午5:02
下一篇 2026年3月17日 下午5:02


相关推荐

  • gitlab搭建与基本使用

    gitlab搭建与基本使用一 git github gitlab 的区别 Git 是版本控制系统 Github 是在线的基于 Git 的代码托管服务 GitHub 是 2008 年由 RubyonRails 编写而成 GitHub 同时提供付费账户和免费账户 这两种账户都可以创建公开的代码仓库 只有付费账户可以创建私有的代码仓库 Gitlab 解决了这个问题 可以在上面创建免费的私人 repo 二 gitlabserver 搭建过程

    2026年3月20日
    2
  • mysql 动静分离_如何动静分离?「建议收藏」

    mysql 动静分离_如何动静分离?「建议收藏」某次面试,hiremanager问我如何做一个大规模的网站,我把我所知道的都讲了,包括squid做的cdncache等等,他又问我,你觉得cdn这部分有什么瓶颈吗?我当时只想到所有动静态请求都路过squid,只是苦苦想着如何去掉动态的请求,他接着问,如何实现?我当时真想不到办法了。后来突然想起看的介绍,实际上我也接触过的,域名分离即可。比如某client的某个请求包含http:/xxx.com…

    2022年6月11日
    29
  • 修改git远程仓库地址

    修改git远程仓库地址由于 git 仓库的地址发生了变化 需要修改仓库地址才能 push 查看本地工程 git 仓库关联的远程仓库地址 gitremote v 删除本地关联的远程仓库地址 gitremoterem 将当前工程关联到指定的远程仓库 gitremoteadd 注意此处 oringe 名称 后续会根据这个名称进行提交将本地代码提交到远程 master 分支 gitpush uoringemaste 打标签查看标签 gitt

    2025年11月7日
    5
  • OpenClaw安全吗?深度解析AI助手安全风险与防护指南

    OpenClaw安全吗?深度解析AI助手安全风险与防护指南

    2026年3月13日
    2
  • SpringBoot使用Websocket(一)

    SpringBoot使用Websocket(一)webSocket是HTML5的一种新协议,它实现了服务端与客户端的全双工通信,建立在传输层,tcp协议之上,即浏览器与服务端需要先建立tcp协议,再发送webSocket连接建立请求。webSocket的连接:客户端发送请求信息,服务端接受到请求并返回相应的信息。连接建立。客户端发送http请求时,通过Upgrade:webSocketConnection:Upgrade告知服务器需要建…

    2022年7月27日
    14
  • Linux【实操篇】—— 日志管理

    Linux【实操篇】—— 日志管理Linux 操作系统日志管理含实操案例

    2026年3月19日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号