老生常谈之js深拷贝与浅拷贝
前言
经常会在一些网站或博客看到“深克隆”,“浅克隆”这两个名词,其实这个很好理解,今天我们就在这里分析一下js深拷贝和浅拷贝。
浅拷贝
我们先以一个例子来说明js浅拷贝:
var n = {a: 1, b: 2}
var m = n
m.a = 12
console.log(n.a) // ?
上面显然 n.a 的值会变为 12,这就是js浅拷贝。浅拷贝只是拷贝的指向对象的指针,本质上还是指向同一个对象。
深拷贝
同样我们还是以一个例子来说明啥叫 js deep clone :
var n = {a: 1, b: 2}
var m = {a: n.a, b: n.b}
m.a = 12
console.log(n.a) // ?
上面的输出结果显然还是 1 ,m 和 n 虽然所有的属性和值全部相同,但是它们是两个不同的对象,它们在堆内存中占据两块不同的内存地址,这就是深度拷贝。深度拷贝就是完全复制一个新的对象出来,它们在堆内存中完全占据两个不同的内存地址。
js 实现深拷贝
简单一维数据结构
- 手动直接赋值
上面的 深拷贝 例子
- 利用 ES6
Object.assign()方法
const obj = {name: 'cc', age: 24}
const newObj = Object.assign({}, obj)
obj.name = 'cc1'
newObj.name ? // cc
二维的数据结构及以上
- 简单粗暴的方式:
JSON.parse(JSON.stringify(obj))。
缺点:它会对对于正则表达式类型、函数类型等无法进行深拷贝,而且会直接丢失相应的值,还有就是它会抛弃对象的 constructor。
var obj = { a: {a: "cc"}, b: 123 }
var newObj = JSON.parse(JSON.stringify(obj))
newObj.b = 1234
console.log(obj) // {a: {a: 'cc'}, b: 123}
console.log(newObj); // {a: {a: 'cc'}, b: 1234}
- 利用 jQuery
// 浅拷贝
var newObj = $.extend({}, obj)
// 深拷贝
var newObj = $.extend(true, {}, obj) // 要求第一个参数必须为true
- 自己动手实现一个简单深拷贝函数
function deepClone(obj){
if(typeof obj !== "object" || obj === null) return
let newObj = obj instanceof Array ? [] : {}
for(let key in obj){
if(obj.hasOwnProperty(key)){
newObj[key] = typeof obj[key] === "object" && obj[key] !== null ? deepClone(obj[key]) : obj[key]
}
}
return newObj
}
let obj = {a: 1, b: function(){}, c: {d: 2}}
deepClone(obj) // {a: 1, b: function(){}, c: {d: 2}}
对于深拷贝来说最常用的就是这些方法,当然还有其他的一些库,比如 deepCopy,lodash等,这里就不深究。
老生常谈之js深拷贝与浅拷贝的更多相关文章
- js 深拷贝和浅拷贝
js 深拷贝和浅拷贝 先举一下项目中遇到的两个例子: 例子1: var json = $.parseJSON(data.data);//data.data是接口返回的值var a = json.cha ...
- 关于JS深拷贝和浅拷贝
最近在前端开发中遇到一些问题,就是数组中的某个对象或某个对象的值改变之后,在不刷新页面的时候需要重新渲染值时,页面显示的还是原来的数据.比如: data{ A:[{id:1,num:1},{id:2, ...
- 在vue中子组件修改props引发的对js深拷贝和浅拷贝的思考
不管是react还是vue,父级组件与子组件的通信都是通过props来实现的,在vue中父组件的props遵循的是单向数据流,用官方的话说就是,父级的props的更新会向下流动到子组件中,反之则不行. ...
- JS 深拷贝和浅拷贝概念,以及实现深拷贝的三种方式
一.理解堆栈,基本数据类型与引用数据类型 1.堆栈 栈(stack):系统自动分配的内存空间,内存会由系统自动释放,用来存放函数的参数值,局部变量的值等,特点是先进后出. 堆(heap):系统动态分配 ...
- 面试遇到的坑JS深拷贝和浅拷贝
首先要搞明白深拷贝和钱拷贝的区别要先搞明白 栈和堆的区别 一.栈 栈存储基础数据类型,如: String.Number.Boolean.Null.Underined,这些简单的基础数据类型能够直接存储 ...
- js深拷贝与浅拷贝
1 基础知识:基本类型与引用类型 JS中可以把变量分成两部分,基本类型和引用类型. 基本类型包括:Undefined.Null.Boolean.Number和String: 引用类型值可能由多个值构成 ...
- js深拷贝、浅拷贝
浅拷贝: 只针对当前对象的属性进行拷贝,若当前对象的属性是引用类型时,这个不考虑,不进行拷贝.若属性是引用类型,拷贝后引用的是地址,如果进行更改,会影响拷贝的原对象属性. 深拷贝:针对当前对象的数据的 ...
- js 深拷贝和浅拷贝理解
作者:进击的袋鼠链接:https://www.zhihu.com/question/23031215/answer/124017500来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...
- [转] js深拷贝和浅拷贝
一.数组的深浅拷贝 在使用JavaScript对数组进行操作的时候,我们经常需要将数组进行备份,事实证明如果只是简单的将它赋予其他变量,那么我们只要更改其中的任何一个,然后其他的也会跟着改变,这就导致 ...
随机推荐
- PassArrayByCopy_test.php
<?php //PassArrayByCopy_test.php $a=array("a","b","c"); function te ...
- Tinkoff Internship Warmup Round 2018 and Codeforces Round #475 (Div. 1)
A. Alternating Sum 就是个等比数列,特判公比为 $1$ 的情况即可. #include <bits/stdc++.h> using namespace std; ; ; ...
- [Algorithm] 118. Pascal's Triangle
Given a non-negative integer numRows, generate the first numRows of Pascal's triangle. In Pascal's t ...
- Softmax与Sigmoid函数的联系
译自:http://willwolf.io/2017/04/19/deriving-the-softmax-from-first-principles/ 本文的原始目标是探索softmax函数与sig ...
- centos7 计划任务简介
概述 就像再windows上有计划任务一样,centos7 自然也有计划任务,而且设置更为灵活,好用.再centos7 上可以利用crontab 来执行计划任务, 依赖与 crond 的系统服务,这个 ...
- nginx 配置状态监控
Nginx有内置一个状态页,需要在编译的时候指定参数--with-http_stub_status_module参数方可打开.也就是说,该功能是由http_stub_status_module模块提供 ...
- springboot修改页面不用重启的设置(idea)
1) “File” -> “Settings” -> “Build,Execution,Deplyment” -> “Compiler”,选中打勾 “Build project ...
- Cut 命令截取不同空格的string
eth0 Link encap:Ethernet HWaddr 00:0C:29:16:79:98 例如这一串中间空格数量不一样cut 是无法截取字段的.所以我们需要把他变成有规律的. 这 ...
- 快速搭建Linux-0.11实验环境
搭这个实验环境主要是为了学习Linux-0.11的代码,那就需要修改代码再次编译来验证自己的想法.主要的实验环境来自实验楼,但是在那上面毕竟不方便,所以就以实验楼上的为基础在自己的虚拟机上搭建一个环境 ...
- Docker 版rocketmq部署
rocketmq 部署启动指南-Docker 版 最近学习使用 rocketmq,需要搭建 rocketmq 服务端,本文主要记录 rocketmq 搭建过程以及这个过程踩到的一些坑. 准备工作# ...