手写深拷贝是一个经常被面试官问到的题目,可是我们通常只考虑对象和数组两种情况,也不考虑成环的情况。下面想分享一个近乎完美的深拷贝代码。
什么是深拷贝?
深拷贝就是对象a和对象b之间没有引用,简单来说就是对象a、b之间没有联系。
初级拷贝方法stringify
1 | let a = { |
- 缺点:
- 不支持函数,不会报错,只是会忽略函数
- 不支持undefined
- 不支持环状结构引用,例如 a.d = a这样
- 不支持date(new Date()),会记录下date的时间
- 不支持正则
- 不支持symbol
原因是因为json只支持几个基本的数据类型,可以去json.org里查找, json只支持七种类型(object、array、string、number、true、false、null)
- 那么stringify支持的没有那么好,那应该怎么处理呢?
- 利用递归来做
针对基本变量
针对对象
针对数组
针对函数
1 | const dist = function (source) { |
考虑source对象成环的情况
用栈的方式记录,如果想效率高一些,可以用hashmap的方式。
考虑爆栈的情况
拷贝RegExp和Date
1 | const a = new RegExp("hi\\d+", "ig") |
- 可以通过source和flag两种方式拿到正则表达式