在JavaScript中,数据类型分为两大类:基本数据类型和复杂数据类型。基本数据类型包括Number、Boolean、String、Null、String),而复杂数据类型包括Object、Function、Array。

而对于基本数据类型来说,复制一个变量值,本质上就是copy了这个变量。一个变量值的修改,不会影响到另外一个变量。

let val = 123;
let copy = val;
console.log(copy); //
val = 456; //修改val的值对copy的值不产生影响
console.log(copy); //

而对于复杂数据类型来说,同基本数据类型实现的不太相同。对于复杂数据类型的复制,要注意的是,变量名只是指向这个对象的指针。当我们将保存对象的一个变量赋值给另一个变量时,实际上复制的是这个指针,而两个变量都指向都一个对象。因此,一个对象的修改,会影响到另外一个对象。

// obj只是指向对象的指针
let obj = {
character: 'peaceful'
};
//copy变量复制了这个指针,指向同一个对象
let copy = obj;
console.log(copy); //{character: 'peaceful'}
obj.character = 'lovely';
console.log(copy); //{character: 'lovely'}

拷贝对象

在JavaScript中,拷贝对象分为两种方式,浅拷贝和深拷贝。

浅拷贝指两个不同的变量存的是同一个对象的地址,即两个变量指向同一块内存区域;深拷贝则是重新分配了一块内存区域来存储复制后的对象,两个变量存的是真正的两个互不影响的变量。

浅拷贝

let objA = {
name: '对象A',
content: '我是A'
};
let copyA = objA; console.log(objA.name); // ==> "对象A"
console.log(copyA.name); // ==> "对象A"

如此即得到了objA的一份浅拷贝copyA,由于指向的是同一个对象,因此在修改objA的同时也是修改了copyA,反之亦然。

Object.assign 的深拷贝与浅拷贝

Object.assign(target, …sources)

如果我们把它的第一个参数target设置为一个空对象 {},同时保证剩余的源对象sources中的属性类型不包含引用类型,则该方法的返回值就是一个与源对象相同的但并不在同一块内存空间另一个对象,即获得了源对象的深拷贝。但是,如果源对象的属性中包含某个对象,也就是这个属性的值指向某个对象,就像下面这样:

var obj = {
name: 'obj name',
content: {
a: 1,
b: 2
}
};

则使用 Object.assign({}, obj) 时,返回的目标对象中的content属性与源对象obj中的content属性指向的同一块内存区域,即对obj下的content属性进行了浅拷贝。因此针对深拷贝,需要使用其他方法,比如自己实现一个深拷贝的方法,或者使用 JSON.parse(JSON.stringify(obj))

另一种浅拷贝 ...操作符:

 let arr = {a:1,b:2}
let arr2 = {...arr}
arr2.a = 2
console.log(arr.a)//
console.log(arr2.a)//

深拷贝

我认为对于对象来说最简单的深拷贝方法就是转成字符串再解析

var obj = {a:1,b:2}
var newObj = JSON.parse(JSON.stringify(obj));
newObj.a=3;
console.log(obj);

另外一种深拷贝方法:递归遍历

var obj = {a:{b:10}};
function deepCopy(obj){
  if ( typeof obj != 'object' ){ // ( obj instanceof Object || obj instanceof Array )
    return obj;
  }
  var newobj = {};
  for ( var attr in obj) {
    newobj[attr] = deepCopy(obj[attr]);
  }
  return newobj;
}
var obj2 = deepCopy(obj);
obj2.a.b = 20;
alert(obj.a.b); //

js 对象拷贝的更多相关文章

  1. js对象拷贝的方法

     对象拷贝的方法是一个难点,尤其是深拷贝.建议把代码都运行下,帮助理解拷贝. 一. json方法 1. 适合情况:  JSON对象的深度克隆.方法是先JSON.stringify() 转为json字符 ...

  2. js对象拷贝遇到的坑

    问题:通过拷贝赋值后,所有的对象的name居然都是C test(){ let person = [{'name':'danny'}] let names = ['A','B','C'] let tem ...

  3. 超实用的JavaScript代码段 Item8 -- js对象的(深)拷贝

    js 对象 浅拷贝 和 深拷贝 1.浅拷贝 拷贝就是把父对像的属性,全部拷贝给子对象. 下面这个函数,就是在做拷贝: var Chinese = { nation:'中国' } var Doctor ...

  4. js对象及元素复制拷贝

    1.数组及对象拷贝: 浅拷贝var b=$.extend(false,{},a);//对象浅拷贝 var a={aa:111,bb:{bb1:22}}; var b=$.extend(false,{} ...

  5. JS 对象(对象遍历,拷贝)

     定义属性 直接 obj.对象 的方法 Object.defineProperty(obj, prop, descriptor) ,这种方法可以设置 或者修改对象属性的访问权限 数据描述符和存取描述符 ...

  6. JS对象复制

    在JavaScript很多人复制一个对象的时候都是直接用"=",因为大家都觉得脚本语言是没有指针.引用.地址之类的,所以直接用"="就可以把一个对象复制给另外一 ...

  7. js 深度拷贝

    js 数据类型 分为2种: 基本数据类型:Undefined.Null.Boolean.Number.String 复杂数据类型:Object.Array.function 他们的区别是在内存中的存储 ...

  8. JS组件系列——表格组件神器:bootstrap table 包含了js对象的定义和对象成员函数的定义

    前言:之前一直在忙着各种什么效果,殊不知最基础的Bootstrap Table用法都没有涉及,罪过,罪过.今天补起来吧.上午博主由零开始自己从头到尾使用了一遍Bootstrap Table ,遇到不少 ...

  9. js对象进行浅复制,深拷贝的方法

    js对象浅拷贝和深拷贝详解   本文为大家分享了JavaScript对象的浅拷贝和深拷贝代码,供大家参考,具体内容如下 1.浅拷贝 拷贝就是把父对像的属性,全部拷贝给子对象. 下面这个函数,就是在做拷 ...

随机推荐

  1. 如何更好的编写async函数

    2018年已经到了5月份,node的4.x版本也已经停止了维护 我司的某个服务也已经切到了8.x,目前正在做koa2.x的迁移 将之前的generator全部替换为async 但是,在替换的过程中,发 ...

  2. vue 使用踩坑 note

    1. 如图,假如large那一行错写成 'large': item.ext_data.isLarge + '' === 'true',, 那么,编译不报错,控制台无提示,模板不输出. 2. vue的t ...

  3. 闲聊 “今日头条Go建千亿级微服务的实践”

      背景    今天跟同事偶然看到<今日头条Go建千亿级微服务的实践>文章,故做了一些探讨,与大家分享下,也欢迎大家多多共同探讨!.     其他资料:   如何理解 Golang 中“不 ...

  4. CentOS在线安装RabbitMQ3.7

    一.通过yum命令在线安装RabbitMQ yum在线安装,简单.快捷.自动安装相关依赖包. 1.安装Erlang环境(RabbitMQ由Erlang语言开发) 1.1)下载rpm安装包 官方地址:h ...

  5. 架构选型之Nodejs与Java

    前言: 身边越来越多的同事谈论Nodejs,谈其异步IO.事件回调.前后台统一一门语言,创业的朋友的第一个创业项目也选择了Nodejs,期望能够使用一种语言节省成本快速完成需求开发.与其他项目组的同事 ...

  6. ZooKeeper 安装、配置

    http://blog.csdn.net/franklysun/article/details/6424582 如题本文介绍的是ZooKeeper 的安装和配置过程,此过程非常简单,关键是如何应用(将 ...

  7. (一)JUnit简介

    单元测试是测试应用程序的功能是否能够按需要正常进行,是一个对单一实体(类或方法)的测试. JUnit是一个Java编程语言的单元测试框架. 单元测试框架是一部分代码,可以确保另一端代码(方法)按预期工 ...

  8. noip 2015 斗地主 大爆搜!!!

    反正肯定是大模拟 但是每一个可以出的牌都搜一定不是最优的 考虑最特殊的出牌方案:顺子(单,对,三) 每一种方案再加上暴力贪心打出剩下的牌的步数 #include<cstdio> #incl ...

  9. BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树

    BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排 ...

  10. 【Canal源码分析】parser工作过程

    本文主要分析的部分是instance启动时,parser的一个启动和工作过程.主要关注的是AbstractEventParser的start()方法中的parseThread. 一.序列图 二.源码分 ...