首页IT科技浅拷贝和深拷贝的方法(浅拷贝与深拷贝)

浅拷贝和深拷贝的方法(浅拷贝与深拷贝)

时间2025-09-18 23:44:32分类IT科技浏览5115
导读:一、数据类型存储 在JavaScript中存在两大数据类型:基本类型、引用类型。...

一                、数据类型存储

在JavaScript中存在两大数据类型:基本类型                         、引用类型                。

基本数据类型存放在栈中                ,是一段简单的数据段                         ,数据大小确定        ,内存空间大小可以分配            ,是直接按值存放的                         ,可以按值访问                         。

引用数据类型存放在堆中            ,变量在栈中保存的是指向堆内存的地址值        ,这个地址值指向对应的对象类型                         ,访问堆内存中的对象是通过地址值访问的        。

二        、浅拷贝

浅拷贝                ,指的是创建新的数据    ,这个数据有着原始数据属性值的一份精确拷贝            。

如果属性是基本类型                         ,拷贝的就是基本类型的值                         。如果属性是引用类型                     ,拷贝的就是内存地址            。

即浅拷贝是拷贝一层        。

下面简单实现一个浅拷贝:

function shallowClone (obj) { const newObj = {} for (let prop in obj) { if (obj.hasOwnProperty(prop)) { newObj[prop] = obj[prop] } } return newObj }

在JavaScript中,存在浅拷贝的现象有:

Object.assign() Array.prototype.slice() Array.prototype.concat() 使用扩展运算符实现的复制

Object.assign()

var obj = { age: 18, nature: [smart, good], names: { name1: fx, name2: xka }, love: function () { console.log(fx is a great girl) } } var newObj = Object.assign({}, fxObj)

slice()

const fxArr = [One, Two, Three] const fxArrs = fxArr.slice(0) fxArrs[1] = love consloe.log(fxArr) // [One, Two, Three] consloe.log(fxArrs) // [One, love, Three]

concat()

const fxArr = [One, Two, Three] const fxArrs = fxArr.concat() fxArrs[1] = love consloe.log(fxArr) // [One, Two, Three] consloe.log(fxArrs) // [One, love, Three]

扩展运算符

const fxArr = [One, Two, Three] const fxArrs = [...fxArr] fxArrs[1] = love consloe.log(fxArr) // [One, Two, Three] consloe.log(fxArrs) // [One, love, Three] 三            、深拷贝

深拷贝开辟一个新的栈                    ,两个对象相同                         ,但是对应两个不同的地址    ,修改一个对象的属性                ,不会改变另一个对象的属性                         。

常见的深拷贝方式有:

_.cloneDeep() jQuery.extend() JSON.stringify() 循环递归

_.cloneDeep()

const _ = require(lodash) const obj1 = { a: 1, b: { f: { g: 1 } }, c: { 1, 2, 3 } } const obj2 = _.cloneDeep(obj1) console.log(obj1.b.f === obj2.b.f) // false

jQuery.extend()

const $ = require(jquery) const obj1 = { a: 1, b: { f: { g: 1 } }, c: { 1, 2, 3 } } const obj2 = $.extend(true, {}, obj1) console.log(obj1.b.f === obj2.b.f) // false

JSON.stringify()

const obj = { name: A, name1: undefined, name2: function () {}, name3: Symbol(A) } const obj2 = JSON.parse(JSON.stringify(obj1)) // 会忽略undefined                         、Symbol            、函数 console.log(obj2) // { name: A }

循环递归

function deepClone (obj, hash = new WeakMap()) { if (obj === null) return obj // 如果是null或者undefined                         ,就不进行拷贝操作 if (obj instanceof Date) return new Date(obj) if (obj instanceof RegExp) return new RegExp(obj) // 可能是对象或者普通的值        ,如果是函数的话不需要深拷贝 if (typeof obj !== Object) return obj // 如果是对象            ,就进行深拷贝 if (hash.get(obj)) return hash.get(obj) let cloneObj = new obj.constructor() // 找到的是所属类型原型上的constructor                         ,而原型上的constructor指向的是当前类本身 hash.set(obj, cloneObj) for (let key in obj) { if (obj.hasOwnProperty(key)) { // 实现一个递归拷贝 cloneObj[key] = deepClone(obj[key], hash) } } return cloneObj } 四        、区别

浅拷贝只复制内存地址            ,而不复制对象本身        ,新旧对象还是共享同一块内存                         ,修改对象属性会影响原对象                。

// 浅拷贝 const obj1 = { name: init, arr: [1, [2, 3], 4] } const obj3 = shallowClone(obj1) // 一个浅拷贝方法 obj3.name = update‘ obj3.arr[1] = [5, 6, 7] // 新旧对象还是共享同一块内存 console.log(obj1, obj1) // obj1 { name: init, arr: [1, [5, 6, 7], 4] } console.log(obj3, obj3) // obj3 { name: update, arr: [1, [5, 6, 7], 4] }

深拷贝会另外创造一个一模一样的对象                ,新对象与原对象不共享内存    ,修改新对象不会改到原对象    。

// 深拷贝 const obj1 = { name: init, arr: [1, [2, 3], 4] } const obj4 = deepClone(obj1) // 一个深拷贝方法 obj4.name = update‘ obj4.arr[1] = [5, 6, 7] // 新对象与原对象不共享内存 console.log(obj1, obj1) // obj1 { name: init, arr: [1, [2, 3], 4] } console.log(obj4, obj4) // obj4 { name: update, arr: [1, [5, 6, 7], 4] }

当拷贝类型为引用类型时:

浅拷贝是拷贝一层                         ,属性为对象时                     ,浅拷贝是复制,两个对象指向同一个地址                         。 深拷贝是递归拷贝深层次                    ,属性为对象时                         ,深拷贝是新开栈    ,两个对象指向不同的地址                     。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
spring mvc 运行原理(学习笔记——SpringMVC简介;SpringMVC处理请求原理简图;SpringMVC搭建框架)