JavaScript对象的浅拷贝与深拷贝

1、JS包含两种数据类型: 值类型(基本类型)和引用类型(对象类型)

  值类型都是简单的数据段(Number、String 、Boolean、Null、Undefined),引用类型是由多个值构成对象(Object 、Array 、Function 、Data等)。

  我们进行变量赋值时,解析器首先要确认的就是这个值是基本类型还是引用类型。

  值类型数据存储在栈(stack)中,栈是内存中一种特殊的数据结构,也称为线性表。变量的位置和变量值的位置是重叠的,也就是说值类型的数据被存储在变量被访问的位置。

  引用类型数据存储在堆(heap)中,堆是内存中的动态区域,相当于自留空间,在程序运行期间会动态分配给代码。堆中存储的一般都是对象,然后通过一个编号传递给栈内变量,这个编号就是所谓的引用指针(point),这样变量和变量值之间是分离的,它们通过指针相联系。当读写数据时,计算机通过变量的指针找到堆中的数据块,并进行操作。

2、对象的浅拷贝

  浅拷贝就是增加一个引用指针(point)指向已存在的内存,浅拷贝只是拷贝了内存的地址,原来的变量跟拷贝出来的变量指向同一内存地址,改变其中某个变量,另一个也会变。

let arr1 = [1,2,3];
let arr2 = arr1;
arr1.push(4);
console.log(arr1); // [1,2,3,4]
console.log(arr2); // [1,2,3,4]

3、深拷贝

  深拷贝就是增加一个引用指针(point),并申请一个新的内存,并且让这个新增加的“指针”指向这个新的内存地址,当我们需要复制原对象而又不能修改原对象的时候,深拷贝是唯一的选择。

3、深拷贝的方法

  黑科技手段。会忽略值为function以及undefied的字段,而且对date类型的支持也不太友好,只能克隆原始对象自身的值,不能克隆它继承的值。

JSON.parse(JSON.stringify(obj))

  递归

function clone(value, isDeep) {
  if (value === null) return null
  if (typeof value !== ‘object‘) return value
  if (Array.isArray(value)) {
    if (isDeep) {
      return value.map(item => clone(item, true))
    }
    return [].concat(value)
  } else {
    if (isDeep) {
      var obj = {}
      Object.keys(value).forEach(item => {
        obj[item] = clone(value[item], true)
      })
      return obj
    }
    return { ...value }
  }
}
var objects = { c: { ‘a‘: 1, e: [1, {f: 2}] }, d: { ‘b‘: 2 } }
var shallow = clone(objects, true)
console.log(shallow.c.e[1]) // { f: 2 }
console.log(shallow.c === objects.c) // false
console.log(shallow.d === objects.d) // false
console.log(shallow === objects) // false

  递归改造(保持原形链的继承)

var clone = function (obj) {
    if(obj === null) return null
    if(typeof obj !== ‘object‘) return obj;
    if(obj.constructor===Date) return new Date(obj);
    if(obj.constructor === RegExp) return new RegExp(obj);
    var newObj = new obj.constructor ();  //保持继承链
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {   //不遍历其原型链上的属性
            var val = obj[key];
            newObj[key] = typeof val === ‘object‘ ? arguments.callee(val) : val; // 使用arguments.callee解除与函数名的耦合
        }
    }
    return newObj;
}; 

原文地址:https://www.cnblogs.com/stronggirlyao/p/9803597.html

时间: 2024-07-30 17:56:32

JavaScript对象的浅拷贝与深拷贝的相关文章

对象复制 - 浅拷贝与深拷贝

前言 在前面的文章中,提到过Java之间如果发生了对象赋值,那么其意义是赋值的两个对象都指向同一片内存区域. 那么,如果我希望得到的是一份新的副本 - 即可以随意更改而不影响原始对象呢? 那就涉及到本文要探讨的话题 - 对象的浅拷贝与深拷贝. 浅拷贝 若对象之间发生浅拷贝,那么首先肯定的是会创建一个新的对象副本(这就不同与对象间的直接赋值). 然后所有域进行简单的直接复制 - 非对象域直接拷贝过来,对象域则拷贝此对象的地址(因为对象在java中的本质就是一个 "指针"). 如何进行浅拷

(一)Python入门-6面向对象编程:11对象的浅拷贝和深拷贝

对象的浅拷贝和深拷贝: 变量的赋值操作 只是形成两个变量,实际还是指向同一个对象. 浅拷贝 Python拷贝一般都是浅拷贝.拷贝时,对象包含的子对象内容不拷贝.因此,源对象 和拷贝对象会引用同一个子对象. 深拷贝 使用copy模块的 deepcopy 函数,递归拷贝对象中包含的子对象.源对象和拷贝对象 所有的子对象也不同. [操作] #测试对象的引用赋值,浅拷贝,深拷贝 import copy class MobilePhone: def __init__(self,cpu,screen): s

js中对象的浅拷贝和深拷贝的区别

js中对象的浅拷贝和深拷贝的区别 浅度拷贝:复制一层对象的属性,并不包括对象里面的为引用类型的数据,当改变拷贝的对象里面的引用类型时,源对象也会改变. 深度拷贝:重新开辟一个内存空间,需要递归拷贝对象里的引用,直到子属性都为基本类型.两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性. 数据的类型: 一般数据(值传递):字符,数值,布尔,undefined 拷贝(复制)时,传递的是值,修改新数据,不会影响老数据 复杂数据(引用传递):对象 拷贝(复制)时,传递的是内存地址的

Javascript中的浅拷贝和深拷贝

很多开发语言中都有浅拷贝和深拷贝的说法,这里简单区分一下它们在Javascript中的区别,以及jQuery中深拷贝的实现. 在谈浅拷贝和深拷贝之前,先要屡清楚Javascript中的按值访问和按引用访问这两个概念. 按值访问是针对基本类型(string.number.boolean.null.undefined).基本类型以值的形式被存放在栈内存中,我们通过变量操作的是栈内存中实际的值. 按引用访问时针对引用类型(Object.Array.Date.RegExp.Function).引用类型以

【OC学习-26】对象的浅拷贝和深拷贝——关键在于属性是否可被拷贝

对象的拷贝分为浅拷贝和深拷贝,浅拷贝就是只拷贝对象,但是属性不拷贝,拷贝出来的对象和原来的对象共用属性,即指向同一个属性地址,深拷贝则相当于不仅拷贝了一个对象还拷贝了它的属性,即完全是两个东西,只不过内容相同而已. 拷贝用到协议,如果这个类创建对象后,这个对象要被拷贝,那么这个类就需要用到拷贝协议,分两种:<NSCopying>和<NSMutableCopying>相当于一个是拷贝,另一个是拷贝后可修改. (1)浅拷贝的案例.有一个Person类,它创建一个person1对象后,用

Javascript/js 的浅拷贝与深拷贝(复制)学习随笔

js变量的数据类型值分基本类型值和引用类型值. 在ES6(ECMAScript6)以前,基本数据类型包括String.Number.Boolean.Undefined.Null. 基本类型值的复制(拷贝) 从一个变量向另一个变量复制基本类型的值.使用赋值操作符 ' = ' 即可. 如: 1 var num1 = 1, num2; 2 num2 = num1; 上述代码定义了两个变量num1.num2.num1初始化值是1,num2是undefined.接着把num1赋值给num2. num1的值

Java对象的浅拷贝和深拷贝&amp;&amp;String类型的赋值

Java中的数据类型分为基本数据类型和引用数据类型.对于这两种数据类型,在进行赋值操作.方法传参或返回值时,会有值传递和引用(地址)传递的差别. 浅拷贝(Shallow Copy): ①对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象.因为是两份不同的数据,所以对其中一个对象的该成员变量值进行修改,不会影响另一个对象拷贝得到的数据. ②对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组.某个类的对象等,那么浅拷贝会进行引用传递,也就是只

Python中的可变对象与不可变对象、浅拷贝与深拷贝

Python中的对象分为可变与不可变,有必要了解一下,这会影响到python对象的赋值与拷贝.而拷贝也有深浅之别. 不可变对象 简单说就是某个对象存放在内存中,这块内存中的值是不能改变的,变量指向这块内存,如果要改变变量的值,只能再开辟一块内存,放入新值,再让变量指向新开辟的内存. #定义三个变量 f=22 n=22 z=f print('f=%s,n=%s,z=%s' %(f,n,z)) print('f的地址:',id(f))#id用于获取变量内存地址 print('n的地址:',id(n)

js对象的浅拷贝与深拷贝

浅拷贝和深拷贝都是对于JS中的引用类型而言的,浅拷贝就只是复制对象的引用(堆和栈的关系,原始(基本)类型Undefined,Null,Boolean,Number和String是存入堆,直接引用,object array 则是存入桟中,只用一个指针来引用值,如果拷贝后的对象发生变化,原对象也会发生变化.只有深拷贝才是真正地对对象的拷贝. 1.浅拷贝 默认是浅拷贝,只是将地址进行了复制,示例如下: //浅拷贝 var obj1={name:"cat"}; var obj2=obj1; o