深拷贝和浅拷贝都是针对的引用类型,

JS中的变量类型分为值类型(基本类型)和引用类型;

对值类型进行复制操作会对值进行一份拷贝,而对引用类型赋值,则会对地址进行拷贝,最终两个变量指向同一份数据

一、先来看看JS中的数据类型

let x = 1;        //number类型
let x = 0.1; //number类型,JS不区分整数值和浮点数值 let x = "hello world"; //由双引号内文本构成字符串
let x = 'javascript'; //单引号内文本同样可以构成字符串 let x = true; // boolean 布尔类型 let x = null;
let x = undefined; //null和undefined很相似,是特殊的类型

JS 中数据分为两种类型:

  • 原始数据类型

    • number
    • string
    • boolean
    • null
    • undefined
  • 对象数据类型
    • array 数组 特殊对象类型
    • function 函数 特殊对象类型
    • object 对象

还有 undefined 和 null,此处暂不讨论

object对象需要注意的点:

  • 对象是可变的,即值是可以修改的
  • 对象的比较并非值得比较

比如:var a = [], b = [];

     a == b;   //false,只有在引用相同(指向的地址相同)时,两个只才会相等

由此可以延伸出 深拷贝和浅拷贝 的问题。

=========================================================================

我们的困惑:

1. 看着相等,却又不等

2. 想要不等,却又相等

那么造成这样问题的原因在哪呢?

> 对象的引用

> 引用只会对地址进行赋值, 所以

1. 不同的变量 a 和 b,他们的地址不同,即使数据相同,本身也不会相等,这是造成困惑一的原因;

2. 而变量 aa 和 bb 指向同一地址,当该地址的数据改变时,所有使用该地址的变量全部改变(同一数据),这是造成困惑二的原因

达不到我们想要的效果,怎么办呢?

二、引用(对象)数据类型的赋值和比较问题

解决办法: 笨办法,也是唯一的方式,既然对象数据类型 是由基本数据类型组成的,而基本数据类型可以正常赋值、比较,那我们就把对象类型变成一个个的基本类型进行操作

方法一: 遍历对象中的内容,一个一个的进行赋值,这样只进行一层拷贝的方式了,就是浅拷贝

// 浅拷贝方法
function shallowClone(source) {
let target = {};
for(leti in source) {
if (source.hasOwnProperty(i)) {
target[i] = source[i];
}
}
return target;
}

方法二: 相对于一层拷贝的浅拷贝,无线层次的拷贝叫做 深拷贝

// 简单深拷贝
function clone(source) {
let target = {};
for(let i in source) {
if (source.hasOwnProperty(i)) {
if (typeof source[i] === 'object') {
target[i] = clone(source[i]); // 判断仍是对象,就进行递归
} else {
target[i] = source[i];
}
}
}
return target;
}

上面 clone 方法 和 shallowClone 方法的 区别就是 多了 递归

但是仍然有些问题需要注意:

  • 参数需要检验
  • 判断是否对象的逻辑不够严谨
  • 需要考虑数组的情况

暂不细说,判断对象可以用此方法:

// 更严谨的判断对象的方法
function isObject(x) {
return Object.prototype.toString.call(x) === '[object Object]';
}

当然我们也可以参考其他方法或使用插件

比如: 简单粗暴的 JSON.parse(JSON.stringify(oldObj))

比如: ES6的assign方法(浅拷贝)

比如: 通过immutableJS实现深拷贝

三、最后

无论 浅拷贝,还是深拷贝 都会带来性能问题(平白的需要遍历,只是重新赋值)

所以我们对象最好写的浅一点,精简一点。。。

详细可以看这篇: https://yanhaijing.com/javascript/2018/10/10/clone-deep/

JavaScript 的 深拷贝和浅拷贝的更多相关文章

  1. javascript对象深拷贝,浅拷贝 ,支持数组

    javascript对象深拷贝,浅拷贝 ,支持数组 经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One meth ...

  2. 也来玩玩 javascript对象深拷贝,浅拷贝

    经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One method of copying an object is ...

  3. JavaScript的深拷贝和浅拷贝总结

    深拷贝和浅拷贝 深拷贝:拷贝实例:浅拷贝:拷贝引用(原对象). 说深拷贝和浅拷贝之前,我先去了解了下高程书上的JavaScript的变量类型: 基本类型:undefined.null.Boolean. ...

  4. JavaScript的深拷贝和浅拷贝

    一.数据类型 数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和对象数据类型.. 1.基本数据类型的特点:直接存储在栈(stack ...

  5. JavaScript的深拷贝与浅拷贝

    深拷贝和浅拷贝是在面试中经常遇到的问题.今天在这里总结一下. 深拷贝与浅拷贝的问题,涉及到JavaScript的变量类型,先来说说变量的类型,变量类型包括基本类型和引用类型. 基本类型:Undefin ...

  6. 详解javascript的深拷贝与浅拷贝

    1. 认识深拷贝和浅拷贝 javascript中一般有按值传递和按引用传递两种复制,按值传递的是基本数据类型(Number,String,Boolean,Null,Undefined),一般存放于内存 ...

  7. JavaScript之深拷贝和浅拷贝

    前言 工作中会经常遇到操作数组.对象的情况,你肯定会将原数组.对象进行‘备份’当真正对其操作时发现备份的也发生改变,此时你一脸懵逼,到时是为啥,不是已经备份了么,怎么备份的数组.对象也会发生变化.如果 ...

  8. javaScript深拷贝和浅拷贝简单梳理

    在了解深拷贝和浅拷贝之前,我们先梳理一下: JavaScript中,分为基本数据类型(原始值)和复杂类型(对象),同时它们各自的数据类型细分下又有好几种数据类型 基本数据类型 数字Number 字符串 ...

  9. 读懂javascript深拷贝与浅拷贝

    1. 认识深拷贝和浅拷贝 javascript中一般有按值传递和按引用传递两种复制,按值传递的是基本数据类型(Number,String,Boolean,Null,Undefined),一般存放于内存 ...

随机推荐

  1. 原创:Kmeans算法实战+改进(java实现)

    kmeans算法的流程:   EM思想很伟大,在处理含有隐式变量的机器学习算法中很有用.聚类算法包括kmeans,高斯混合聚类,快速迭代聚类等等,都离不开EM思想.在了解kmeans算法之前,有必要详 ...

  2. SpringBoot:使用Jenkins自动部署SpringBoot项目(二)具体配置

    1.启动Jenkins 在浏览器输入ip:port后,进入Jenkins初始化界面,需要查看文件,得到密码. 输入密码进入初始化界面,选择推荐插件安装. 安装完成创建账号,进入Jenkins主界面. ...

  3. Internet地址结构

    IP地址结构及分类寻址 IP地址 = <网络号> + <主机号>            ------------IPv4(32bit)点分四组表示法: 192.168.31.1 ...

  4. Java中的long类型和Long类型比较大小

    Java中我们经常要做一些判断,而对于判断的话,用的最多的便是“>”.“==”.“<”的比较,这里我们进行一个Long类型数据和long类型数据的比较大小的讲解. Java中Long和lo ...

  5. 创建第一个react项目

    前提:已安装部署好nodejs环境 查看nodejs是否安装以及版本 1,win+r输入cmd打开命令行页面 2,路径换到nodejs目录 3,输入node -v查看版本 创建项目 1,win+r输入 ...

  6. 一口气讲完 LSA — PlSA —LDA在自然语言处理中的使用

    自然语言处理之LSA LSA(Latent Semantic Analysis), 潜在语义分析.试图利用文档中隐藏的潜在的概念来进行文档分析与检索,能够达到比直接的关键词匹配获得更好的效果. LSA ...

  7. SonarQube7.4安装和使用

    声明 本文转自:https://www.jianshu.com/p/dd4a4bc59fc3?from=singlemessage 正文 近期比较关注代码的检测,之前由于用的findbugs,因此没有 ...

  8. 取response里 Json格式的字段值

    1.

  9. 运维笔记--Docker文件占用磁盘空间异常处理

    场景描述: 1. 服务器运行一段时间后,发现系统盘磁盘空间在不断增加,一开始的时候,不会影响系统,随着时间的推移,磁盘空间在不断增加,直到有一天你会发现系统盘剩余空间即将使用完,值得庆幸的是,如果您使 ...

  10. docker入门-基本概念(一)

    Docker是什么 Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源. Docker的应用场景 Web 应用的自动化打包和发布. 自动化测试和持续集成.发 ...