JavaScript复制对象和数组

JavaScript 中,数据类型分为两大类型,基本类型和引用类型。

简述一下,基本类型是指我们常见的Undefined、Null、String、Number、Boolean,是保存在 栈内存 中的简单数据段;而引用类型则是指Object、Array、RegExp、Date、Function、特殊的基本包装类型(String、Number、Boolean)以及单体内置对象(Global、Math)。

先来了解一下最常见的Object和Array,作为最常用引用类型,Object本身是个键值对的集合,组成一个拥有多属性的数据。Array则是个有序的数据列表。两者都能储存各种基本类型数据。

在JavaScript声明变量的过程中,对Object和Array的声明实际上并不是给变量赋值,而是类似于C语言中的指针,将变量指向于 堆内存 中,通过变量名寻址找到相应的对象。当没有任何变量指向于该对象时,现代浏览器会进行销毁回收内存空间。

所以在对JavaScript了解不够的时候,经常会对引用类型进行类似于以下的操作:

var a = { key: 'test' }
var b = a

// 更改key的值
b.key = 1

这种操作会直接导致两个变量引用的对象值发生变化,当重新访问 a.key 的,实际拿到的就是 1 了,这个就是我们常说的浅复制。

那么怎么操作才能复制好一个对象出来呢?不妨思考一下,上文可以得知,对象和数组的组成其实就是我们常用的基本类型或引用类型组成的,要复制他们,其实就是创建出相同的数据结构,把对应的值赋上去,,而引用类型中包含引用类型,则也可以执行上述操作,直到复制出两个对象。

以下用递归实现一下原理。

/** 
 * 深度复制朴素对象和数组
 * 除此之外都做浅复制处理
 * @author chen-rongliang@qq.com
 * @param obejcts
 * 待复制变量
 * @return 合并的对象
 * @example
 * 
 *  var extend = require('./extend')
 *  var y = {
 *          a: 1,
 *          b: '2',
 *          c: { d: [3] }
 *      },
 *      z = {
 *          a: 2,
 *          e: 6,
 *          f: {
 *              g: 7
 *          }
 *      }
 *
 *  var x = extend(y, z)
 *
 *  x.c.d = 999
 *  z.f.g = 8
 *
 *
 */

const Extend = (obj, temp) => {

    // 类型
    let typeStr = obj.constructor.name

    // 类型为朴素对象或数组
    if (typeStr === 'Object' || typeStr === 'Array') {

        // 副本初始化类型
        if (temp === undefined) {
            temp = obj instanceof Array ? [] : {}
        }

        // 遍历
        for (let key in obj) {

            // 如果遍历子也是复杂类型,递归调用
            if (obj[key] instanceof Object) {

                temp[key] = Extend(obj[key])

            } else {

                // 直接赋值
                temp[key] = obj[key]

            }
        }
    } else {

        // 简单类型 / 非数组 / 非朴素对象 直接复制
        temp = obj

    }

    return temp

}

module.exports = (...objs) => {

    let concats = {}

    for (let obj of objs) {
        Extend(obj, concats)
    }

    return concats

}

除了这种方法,代码实现还有各种各样的,这个就不一一介绍了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值